[英]window.onload works in Firefox+Greasemonkey script but not in a Chrome userscript?
There is a page http://example.com/1.php that includes javascript file as usual: 有一个页面http://example.com/1.php像往常一样包含javascript文件:
<script type="text/javascript" src="/util.js?1354729400"></script>
This file contain function named exampleFunction which I need to use in my userscript. 这个文件包含名为exampleFunction的函数,我需要在我的用户脚本中使用它。 Also I have an user script:
我还有一个用户脚本:
// ==UserScript==
// @name SomeName
// @namespace http://example.com/userscripts
// @description Greets the world
// @include http://example.com/*
// ==/UserScript==
window.onload = function () {
console.log(exampleFunction);
alert("LOADED!");
}
which works perfectly in Firefox and returns an error in Chrome: 在Firefox中完美运行并在Chrome中返回错误:
Uncaught ReferenceError: exampleFunction is not defined
How do I make it work? 我如何使其工作?
The reason that exampleFunction
was undefined is because Chrome userscripts operate in a sandbox ( "isolated world" ). exampleFunction
未定义的原因是因为Chrome用户脚本在沙箱中运行( “孤立世界” )。 Note that Greasemonkey scripts often operate in a sandbox too, but yours is currently running with an implicit @grant none
. 请注意,Greasemonkey脚本通常也在沙箱中运行,但是您的脚本当前正在使用隐式
@grant none
运行。
If your script were to use a GM_
function, it would stop working in Firefox too. 如果您的脚本使用
GM_
函数,它也将停止在Firefox中运行。
To make this script work on both browsers (and a few others, as well), use Script Injection similar to this answer . 要使此脚本在两个浏览器(以及其他一些浏览器)上运行,请使用类似于此答案的 脚本注入 。
However , there is another hitch, since that script is using window.onload
. 但是 ,还有另一个问题,因为该脚本使用的是
window.onload
。 Chrome userscripts, with the default execution start-mode, will often never see the onload
event. 使用默认执行启动模式的Chrome用户脚本通常永远不会看到
onload
事件。
To get around that, add // @run-at document-end
to the metadata block. 要解决这个问题,请将
// @run-at document-end
到元数据块。
So the script becomes: 所以脚本变成:
// ==UserScript==
// @name SomeName
// @namespace http://example.com/userscripts
// @description Greets the world
// @include http://example.com/*
// @run-at document-end
// @grant none
// ==/UserScript==
function GM_main () {
window.onload = function () {
console.log(exampleFunction);
alert("LOADED!");
}
}
addJS_Node (null, null, GM_main);
//-- This is a standard-ish utility function:
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);
}
If you want the equivalent to onLoad
, which doesn't fire till all images on the page are loaded, you want to use // @run-at document-idle
in your metadata block. 如果你想要等同于
onLoad
,它在页面上的所有图像都被加载之前不会触发,你想在元数据块中使用// @run-at document-idle
。 The default, document-end, fires when the DOM is loaded, the equivalent of document.ready. 加载DOM时会触发默认的document-end,相当于document.ready。
Have you tried calling examplefunction with brackets ? 你试过用括号调用examplefunction吗? :) Like this:
:) 像这样:
console.log(exampleFunction());
If you try it in chrome console, you have to add brackets to call function. 如果您在chrome控制台中尝试它,则必须为调用函数添加括号。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.