42

FirefoxとOperaで問題なく動作するGreasemonkeyスクリプトがあります。ただし、Chromeで動作させるのに苦労しています。問題は、ページからコードによって呼び出すことができる関数をページに挿入することです。これが私がこれまでに行っていることです:

まず、 FirefoxのunsafeWindowへのヘルパーリファレンスを取得します。これにより、FFとOpera(およびChrome)で同じコードを使用できるようになります。

var uw = (this.unsafeWindow) ? this.unsafeWindow : window;

次に、ページに関数を挿入します。これは実際には非常に薄いラッパーであり、GMスクリプトのコンテキストで対応する関数を呼び出すだけです。

uw.setConfigOption = function(newValue) {
    setTimeout(setConfigOption, 0, newValue);
}

次に、私のスクリプトに対応する関数があります。

setConfigOption = function(newValue) {
    // do something with it, e.g. store in localStorage
}

最後に、関数を呼び出すためのリンクを含むHTMLをページに挿入します。

var p = document.createElement('p');
p.innerHTML = '<a href="javascript:setConfigOption(1)">set config option to 1</a>';
document.getElementById('injection-point').appendChild(p);

要約すると、Firefoxでは、ユーザーがその挿入されたリンクをクリックすると、unsafeWindowで関数呼び出しが実行され、GMスクリプトのコンテキストで対応する関数を呼び出すタイムアウトがトリガーされ、実際の処理が実行されます。(ここで間違っている場合は訂正してください。)

Chromeでは、「Uncaught ReferenceError:setConfigOptionisnotdefined」エラーが発生します。実際、コンソールに「window.setConfigOption」と入力すると、「undefined」が生成されます。FirebugとOpera開発者コンソールには、機能があります。

これを行う別の方法があるかもしれませんが、私の関数のいくつかはページ上のFlashオブジェクトによって呼び出されるため、ページコンテキストに関数がある必要があると思います。

私はGreasemonkeywikiでunsafeWindowの代替案をざっと見てみましたが、それらはすべてかなり醜いように見えます。私はここで完全に間違った方向に進んでいますか、それともこれらをもっと詳しく調べる必要がありますか?

解決策:MaxSをフォローしました。アドバイスとそれは今FirefoxとChromeの両方で動作します。ページで使用できるようにする必要のある関数を通常の関数にコールバックする必要があったため、スクリプト全体をページに移動しました。つまり、彼が「main()」と呼んだ関数に完全にラップされています。

そのハックの余分な醜さをもう少し耐えられるようにするために、少なくともunsafeWindowとwrappedJSObjectの使用をやめることができます。

私はまだGreasemonkeywikiからコンテンツスコープランナーを機能させることができていません。同じように動作するはずで、正常に実行されているように見えますが<a>、たとえば、ページの要素から関数にアクセスすることはできません。それがなぜなのか、私はまだ理解していません。

4

4 に答える 4

72

Chrome のページで実行されているコードと通信するには DOM を使用するしかないため、<script>コードにタグを挿入するなどのハックを使用する必要があります。ページ上の他のすべてよりも前にスクリプトを実行する必要がある場合、これはバグであることが判明する可能性があることに注意してください。

編集: Nice Alert 拡張機能がこれを行う方法は次のとおりです。

function main () {
  // ...
  window.alert = function() {/* ... */};
  // ...
}

var script = document.createElement('script');
script.appendChild(document.createTextNode('('+ main +')();'));
(document.body || document.head || document.documentElement).appendChild(script);
于 2010-02-20T18:45:02.950 に答える
15

私はこれを持っています:

contentscript.js:

function injectJs(link) {
var scr = document.createElement('script');
scr.type="text/javascript";
scr.src=link;
document.getElementsByTagName('head')[0].appendChild(scr)
//document.body.appendChild(scr);
}

injectJs(chrome.extension.getURL('injected.js'));

Injection.js:

function main() {
     alert('Hello World!');
}

main();
于 2010-02-26T17:34:06.857 に答える
4

Greasemonkey wiki でunsafeWindowの代替案をざっと見てみましたが、どれも見栄えがよくありません。ここで私は完全に間違った方向に進んでいますか、それともこれらをもっと詳しく調べる必要がありますか?

それは利用可能なオプションだけなので、見てください。location hackを使用することをお勧めします。

myscript.user.js:

function myFunc(){
  alert('Hello World!');
}

location.href="javascript:(function(){" + myFunc + "})()"

example.com/mypage.html

<script>
myFunc() // Hello World!
</script>

確かに、それは醜いです。しかし、それはうまく機能しています。


Max S. が言及した Content Scope Runner メソッドは、デバッグが容易なため、ロケーション ハックよりも優れています。

于 2010-02-20T18:54:32.887 に答える