我有一个在 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);
}
而且它不起作用... 我做错了什么?
最佳答案
如果 toAlert
恰好在页面的全局范围内定义,则您的脚本将起作用。
在 Chrome 中,扩展程序/Greasemonkey JavaScript 无法与页面 JavaScript 共享变量或闭包。
这就是为什么您不能直接将该函数从扩展范围注入(inject)到页面范围,而必须从源字符串重新创建它。
这意味着,如果您在页面范围内创建函数,则函数所需的任何变量或函数必须:
- 已经出现在全局范围内的源页面中。
或者 - 也可以将脚本编写到源页面中。
例如,像这样修改你的代码......
//-- 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() 函数中,并将其编写到源页面中。
像这样:
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()
。
关于javascript - 使用用户脚本中的变量在 Google Chrome 页面中注入(inject) JS?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3671930/