我有一个在FireFox中使用unsafeWindow的脚本,因为那不起作用,我已经搜索了另一个选项,并找到了它,我只是想知道:我如何使用我的用户脚本中的变量进入unsafeWindow变通方法?
我的代码是:
// ==UserScript==
// @name Test
// @description Test
// @include http://www.google*
// ==/UserScript==
var toAlert = "This is what I want to alert...";
alert("Before implementation...");
contentEval( function(){ alert(toAlert);});
alert("And after...");
function contentEval(source) {
// Check for function input.
if ('function' == typeof source) {
// Execute this function with no arguments, by adding parentheses.
// One set around the function, required for valid syntax, and a
// second empty set calls the surrounded function.
source = '(' + source + ')();'
}
// Create a script node holding this source code.
var script = document.createElement('script');
script.setAttribute("type", "application/javascript");
script.textContent = source;
// Insert the script node into the page, so it will run, and immediately
// remove it to clean up.
document.body.appendChild(script);
document.body.removeChild(script);
}
它不起作用...... 我做错了什么?
答案 0 :(得分:4)
如果恰好在页面的全局范围内定义了toAlert
,那么您的脚本将会起作用。
在Chrome中,扩展程序/ Greasemonkey JavaScript无法与页面JavaScript共享变量或闭包 这就是为什么你不能直接从扩展范围注入该函数到页面范围,但必须从源字符串重新创建它。
这意味着如果在页面范围中创建函数,则函数需要的任何变量或函数必须:
例如,像这样修改你的代码......
//-- Must recreate the variable that the function requires.
scriptStr = 'var toAlert="' + toAlert +'";';
//-- Now the function.
scriptStr += '(' + source.toString() + ')();'
var script = document.createElement('script');
script.textContent = scriptStr;
......有效,但这种做法显然很混乱。
聪明的做法是: (A)将所有JavaScript保留在扩展中;不要与页面的JavaScript交互。
或者(B)如果你必须与页面的JS交互,或者加载像jQuery这样的库,那么将所有代码放在一个main()函数中,并将其编入源页面。< / p>
像这样:
function localMain ()
{
/*--- Put EVERYTHING inside this wrapper, functions and variables.
Call or use nothing else that's defined in the GM script here.
Can use objects in the source page's scope, though.
*/
}
//--- Now create the function in the page's scope and run it.
var scriptNode = document.createElement ("script");
scriptNode.textContent = localMain.toString() + "\n localMain ();";
document.head.appendChild (scriptNode);
请注意,如果您还要将库加载到页面范围内,则可能需要通过使用计时器和检查该库来延迟运行localMain()
。