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)or$('frame#main').contents()[0].createElement('script')

  • window.frames["#main"].contentWindow返回未定义。

我已经尝试了许多其他我现在不记得的事情,但是我已经用尽了所有的想法,并且觉得我在打字比任何重要的东西都多。
我不知道如何使用unsafeWindowiFrame。

4

1 回答 1

10
  1. unsafeWindow在 Chrome、Tampermonkey 或 Firefox 上不能很好地处理帧/iframe。
  2. 像这样尝试使用 jQuery 访问全局(到框架)JS 是行不通的。
  3. @include用户脚本将在满足、@exclude和/或@match要求的 iframe 上运行。

因此,您需要考虑多个脚本运行,然后您有两种基本方法,具体取决于您要完成的任务。你可以:

(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)将是:

Tampermonkey 开始
脚本开始...
调用functionOfInterest()...
用户脚本位于 MAIN 页面中。
脚本结束
Tampermonkey 开始
脚本开始...
调用functionOfInterest()...
用户脚本位于 FRAMED 页面中。
框架的 ID 是:iframe2
脚本结束

1unsafeWindow如果您删除这些行,它也可以作为直接的 Chrome 用户脚本使用。

于 2012-07-25T08:31:51.500 回答