关于javascript:window.onload适用于Firefox + Greasemonkey脚本,但不适用于Chrome用户脚本?

window.onload works in Firefox+Greasemonkey script but not in a Chrome userscript?

有一个页http:///1.php example.com,包括JavaScript文件如常。

1
<script type="text/javascript" src="/util.js?1354729400">

本文件包含的功能examplefunction命名,它在我的userscript需要使用。所以我有一个用户脚本:

1
2
3
4
5
6
7
8
9
10
// ==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!");
}

这工作完全在Firefox和Chrome的返回错误

1
Uncaught ReferenceError: exampleFunction is not defined

我如何使它工作吗?


exampleFunction未定义的原因是因为chrome用户脚本在沙盒("孤立的世界")中操作。注意,greasemonkey脚本也经常在沙盒中运行,但是您当前使用的是隐式@grant none。如果您的脚本要使用GM_函数,它也将停止在firefox中工作。

为了使这个脚本在两个浏览器(以及其他一些浏览器)上都能工作,使用类似于这个答案的脚本注入。

但是,还有另一个障碍,因为该脚本正在使用window.onload。使用默认执行启动模式的chrome用户脚本通常不会看到onload事件。

为了解决这个问题,将// @run-at document-end添加到元数据块中。

所以脚本变成:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// ==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);
}


如果您希望等效于onload,在加载页面上的所有图像之前,它不会启动,那么您希望在元数据块中使用// @run-at document-idle。当加载dom时,将激发默认的document end,相当于document.ready。


您试过用括号调用ExampleFunction吗?:)这样地:

1
console.log(exampleFunction());

如果在chrome控制台中尝试,则必须添加括号才能调用函数。