我在 test.js 中有以下代码,它在< / body>之前运行:
alert('stovetop');
alert(greasy);
我在 test.user.js 中有以下代码:
(function () {
'use strict';
var greasy = 'greasy variable';
document.title = 'greasy title';
}());
document.title
会有变化,所以我知道脚本javascript有效。但是,在网页上我收到错误:
错误:ReferenceError:greasy未定义源文件:/test.js
如何从网页访问Greasemonkey设置的变量,反之亦然?
答案 0 :(得分:27)
Greasemonkey脚本在单独的范围内运行,也可能在沙箱中运行,具体取决于@grant
settings。
此外,问题代码在函数范围内隔离greasy
(正如gladoscc所说)。
最后,默认情况下, test.js 将在Greasemonkey脚本执行之前触发,因此无论如何都不会看到任何设置变量。使用@run-at document-start
解决此问题。
因此,鉴于此 test.js ,请在</body>
之前运行:
window.targetPages_GlobalVar = 'stovetop';
console.log ("On target page, local global: ", targetPages_GlobalVar);
console.log ("On target page, script global: ", gmScripts_GlobalVar);
然后以下内容将起作用:
没有沙箱:
// ==UserScript==
// @name _Greasemonkey and target page, variable interaction
// @include http://YOUR_SERVER.COM/YOUR_PATH/*
// @include http://jsbin.com/esikut/*
// @run-at document-start
// @grant none
// ==/UserScript==
//--- For @grant none, could also use window. instead of unsafeWindow.
unsafeWindow.gmScripts_GlobalVar = 'greasy';
console.log ("In GM script, local global: ", unsafeWindow.targetPages_GlobalVar);
console.log ("In GM script, script global: ", gmScripts_GlobalVar);
window.addEventListener ("DOMContentLoaded", function() {
console.log ("In GM script, local global, after ready: ", unsafeWindow.targetPages_GlobalVar);
}, false);
使用沙箱,没有功能范围,unsafeWindow
:
==&GT; 重要更新: Greasemonkey changed unsafeWindow handling with version 2.0, the next sample script will not work with GM 2.0 or later。其他两个解决方案仍然有效。
// ==UserScript==
// @name _Greasemonkey and target page, variable interaction
// @include http://YOUR_SERVER.COM/YOUR_PATH/*
// @include http://jsbin.com/esikut/*
// @run-at document-start
// @grant GM_addStyle
// ==/UserScript==
/*- The @grant directive is needed to work around a design change
introduced in GM 1.0. It restores the sandbox.
*/
unsafeWindow.gmScripts_GlobalVar = 'greasy';
console.log ("In GM script, local global: ", unsafeWindow.targetPages_GlobalVar);
console.log ("In GM script, script global: ", unsafeWindow.gmScripts_GlobalVar);
window.addEventListener ("DOMContentLoaded", function() {
console.log ("In GM script, local global, after ready: ", unsafeWindow.targetPages_GlobalVar);
}, false);
使用沙箱,没有功能范围,脚本注入:
// ==UserScript==
// @name _Greasemonkey and target page, variable interaction
// @include http://YOUR_SERVER.COM/YOUR_PATH/*
// @include http://jsbin.com/esikut/*
// @run-at document-start
// @grant GM_addStyle
// ==/UserScript==
/*- The @grant directive is needed to work around a design change
introduced in GM 1.0. It restores the sandbox.
*/
function GM_main () {
window.gmScripts_GlobalVar = 'greasy';
console.log ("In GM script, local global: ", window.targetPages_GlobalVar);
console.log ("In GM script, script global: ", window.gmScripts_GlobalVar);
window.addEventListener ("DOMContentLoaded", function() {
console.log ("In GM script, local global, after ready: ", window.targetPages_GlobalVar);
}, false);
}
addJS_Node (null, null, GM_main);
function addJS_Node (text, s_URL, funcToRun, runOnLoad) {
var D = document;
var scriptNode = D.createElement ('script');
if (runOnLoad) {
scriptNode.addEventListener ("load", runOnLoad, false);
}
scriptNode.type = "text/javascript";
if (text) scriptNode.textContent = text;
if (s_URL) scriptNode.src = s_URL;
if (funcToRun) scriptNode.textContent = '(' + funcToRun.toString() + ')()';
var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
targ.appendChild (scriptNode);
}
注意:
unsafeWindow
和window
都是相同的。所有这些脚本在控制台上产生相同的输出:
In GM script, local global: undefined
In GM script, script global: greasy
On target page, local global: stovetop
On target page, script global: greasy
In GM script, local global, after ready: stovetop
除了Firefox之外,脚本注入代码可以在各种浏览器中使用。 unsafeWindow
目前仅适用于Firefox + Greasemonkey(或Scriptish)或Chrome + Tampermonkey。
答案 1 :(得分:1)
您的变量greasy
在匿名函数的范围内定义。即使在您的用户脚本中也无法访问greasy
,除非它是您的功能的一部分。例如:
(function(){
var foo = 5;
alert(foo);
}();
alert(foo); //ERROR, because foo is undefined outside of the function.
这样做:
var foo = 5;
(function(){
alert(foo);
}();
alert(foo);
另外,为什么要将所有代码放在匿名函数中然后执行它?
答案 2 :(得分:0)
您也可以使用localStorage:
localStorage.setItem("numberOfThings", "42");
localStorage.getItem("numberOfThings");