javascript - 如何从用户脚本访问 iframe 的 javascript?

标签 javascript google-chrome iframe greasemonkey tampermonkey

我正在尝试使用 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"].contentWindow 返回未定义。

我尝试过很多其他的东西,我现在想不起来了,但我已经用尽了所有的想法,觉得我在输入垃圾比什么都重要。
我不知道如何使用 iFrame 的 unsafeWindow

最佳答案

  1. unsafeWindow 与 Chrome、Tampermonkey 或 Firefox 上的框架/iframe 不兼容。
  2. 像那样尝试使用 jQuery 访问全局(到框架)JS 是行不通的。
  3. 用户脚本将在满足 @include@exclude 和/或 @match 要求的 iframe 上运行。

因此,您需要考虑多个脚本运行,然后您有两种基本方法,具体取决于您要实现的目标。您可以:

(A) 为特定帧定制脚本,如 this answer .

或 (B) 注入(inject)您的 JS 并使用特殊的 frames 对象来获取您想要的特定功能。

以下脚本演示了两者。在Tampermonkey1(或Firefox Greasemonkey)中安装,然后访问this test page at 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 started
Script start...
calling functionOfInterest ()...
Userscript is in the MAIN page.
Script end
Tampermonkey started
Script start...
calling functionOfInterest ()...
Userscript is in the FRAMED page.
The frame's ID is: iframe2
Script end

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

关于javascript - 如何从用户脚本访问 iframe 的 javascript?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11638595/

相关文章:

javascript - 在网络墨卡托中以任意浮点缩放级别转换纬度/经度和像素?

node.js - 我可以将文件从 node-webkit 应用程序中拖出并放到桌面上吗?

php - Jquery 切换行为不一致

ios - Chrome iOS webkit 语音识别

Javascript,从 iFrame 访问框架集中的嵌套框架

javascript - 如何让 iframe 从另一个页面上的链接加载内容?

Javascript Regex 确保最后 3 个字符是数字?

javascript - 如何让这个倒数计时器倒计时到特定日期,而不仅仅是从一个时间开始?

javascript - 如何更改 iframe 谷歌地图的坐标以根据传递的坐标打印不同的结果

javascript - 组件不在 native react 中呈现