我正在尝试使用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
返回undefined。
我已经尝试了许多其他我不记得的事情,但是我已经用尽了所有的想法,觉得我输的垃圾比任何重要的东西都要多。
我无法弄清楚如何使用iFrame的unsafeWindow
。
答案 0 :(得分:10)
unsafeWindow
与Chrome,Tampermonkey或Firefox上的框架/ iframe不相称。 @include
,@exclude
和/或@match
要求的iframe上投放。因此,您需要考虑多个脚本运行,然后您有两种基本方法,具体取决于您要完成的任务。你可以:
(A)将脚本定制到特定的框架,如this answer。
或(B)注入你的JS并使用特殊的frames
对象来获取你想要的特定功能。
以下脚本演示了两者。将其安装在Tampermonkey 1 (或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用户脚本。