unsafeWindow
在 Chrome、Tampermonkey 或 Firefox 上不能很好地处理帧/iframe。
- 像这样尝试使用 jQuery 访问全局(到框架)JS 是行不通的。
@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 用户脚本使用。