5

ChromeユーザースクリプトまたはTampermonkeyスクリプトを使用して、次の構造のページを変更しようとしています。

<body>
content up here

<iframe id="main" src="foo.dat"></iframe>
</body>

iframeは同一生成元です。

にある関数にアクセスする必要がありますiframe#main。私はそれを手に入れるために使うことができると思っunsafeWindowたが、私は何も得られないか、undefined戻ってきた。

私はたくさんのことを試しました:

  • で新しいスクリプト要素を作成しようとしましたが、またはを使用iframeしても親にアタッチされます$('frame#main').contents().append(script)$('frame#main').contents()[0].createElement('script')

  • window.frames["#main"].contentWindowundefinedを返します。

現時点では思い出せないことを他にもたくさん試しましたが、すべてのアイデアを使い果たして、何よりもゴミを入力していると感じています。iFrame
ので遊ぶ方法がわかりません。unsafeWindow

4

1 に答える 1

10
  1. unsafeWindowChrome、Tampermonkey、またはFirefoxのフレーム/iframeではうまく機能しません。
  2. このように、jQueryを使用してグローバル(フレーム)JSにアクセスしようとしても機能しません。
  3. @includeユーザースクリプトは、、、@excludeおよび/または@match要件を満たすiframe上で実行されます。

したがって、複数のスクリプトの実行を考慮する必要があります。次に、達成しようとしていることに応じて、2つの基本的なアプローチがあります。あなたはできる:

(A)この回答のように、スクリプトを特定のフレームに合わせて調整します。

または(B)JSを注入し、特別なframesオブジェクトを使用して、必要な特定の関数を取得します。

次のスクリプトは両方を示しています。Tampermonkey 1(またはFirefox Greasemonkey)にインストールしてから、jsBinのこのテストページにアクセスしてください

// ==UserScript==
// @name        _Calling iframe functions
// @namespace   _pc
// @include     http://jsbin.com/ugoruz/*
// @include     http://jsbin.com/okequw/*
// ==/UserScript==

console.log ("Script start...");

/*--- This next function call will work in Firefox or Tampermonkey ONLY,
    not pure Chrome userscript.
*/
console.log ("calling functionOfInterest ()...");
unsafeWindow.functionOfInterest ();


if (window.top === window.self) {
    //--- Code to run when page is the main site...
    console.log ("Userscript is in the MAIN page.");

    //--- The frames object does not play nice with unsafeWindow.
    /*--- These next three work in Firefox, but not Tampermonkey, nor pure Chrome.
    console.log ("1", frames[1].variableOfInterest);                // undefined
    console.log ("2", unsafeWindow.frames[1].variableOfInterest);   // undefined
    console.log ("3", frames[1].unsafeWindow);                      // undefined
    */
    /*--- This next would cause a silent crash, all browsers...
    console.log ("4", unsafeWindow.frames[1].unsafeWindow.variableOfInterest);
    */

    //--- To get at iFramed JS, we must inject our JS.
    withPages_jQuery (demoAccessToFramedJS);
}
else {
    //--- Code to run when page is in an iframe...
    console.log ("Userscript is in the FRAMED page.");
    console.log ("The frame's ID is:", window.self.frameElement.id);
}


function demoAccessToFramedJS ($) {
    $("body").prepend (
          '<button id="gmMain">Run JS on main window</button>'
        + '<button id="gmFrame">Run JS on iframe</button>'
    );

    $("#gmMain, #gmFrame").click ( function () {
        if (this.id === "gmMain") {
            functionOfInterest ();
        }
        else {
            frames[1].functionOfInterest ();
        }
        console.log (this.id + "was clicked.");
    } );
}

function withPages_jQuery (NAMED_FunctionToRun) {
    //--- Use named functions for clarity and debugging...
    var funcText        = NAMED_FunctionToRun.toString ();
    var funcName        = funcText.replace (/^function\s+(\w+)\s*\((.|\n|\r)+$/, "$1");
    var script          = document.createElement ("script");
    script.textContent  = funcText + "\n\n";
    script.textContent += 'jQuery(document).ready(function() {'+funcName+'(jQuery);});';
    document.body.appendChild (script);
};

console.log ("Script end");



スクリプトがメインページとiframeの両方から関数を実行していることがわかります。コンソール出力(Tampermonkey)は次のようになります。

タンパーモンキーが始まりました
スクリプトの開始...
functionOfInterest()..を呼び出します。
ユーザースクリプトはメインページにあります。
スクリプト終了
タンパーモンキーが始まりました
スクリプトの開始...
functionOfInterest()..を呼び出します。
ユーザースクリプトはFRAMEDページにあります。
フレームのIDは次のとおりです。iframe2
スクリプト終了

1行を削除すると、まっすぐなChromeユーザースクリプトとしても機能しますunsafeWindow

于 2012-07-25T08:31:51.500 に答える