7

有一个页面http://example.com/1.php像往常一样包含 javascript 文件:

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

该文件包含名为exampleFunction的函数,我需要在我的用户脚本中使用它。我还有一个用户脚本:

// ==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 中返回错误:

Uncaught ReferenceError: exampleFunction is not defined 

我如何使它工作?

4

3 回答 3

9

未定义的原因exampleFunction是 Chrome 用户脚本在沙箱(“孤立世界”)中运行。请注意,Greasemonkey 脚本也经常在沙箱中运行,但您的当前正在使用隐式@grant none.
如果你的脚本要使用一个GM_函数,它也会在 Firefox 中停止工作。

要使此脚本在两种浏览器(以及其他一些浏览器)上都可以工作,请使用类似于此答案的脚本注入

但是,还有另一个问题,因为该脚本使用window.onload. 具有默认执行启动模式的 Chrome 用户脚本通常永远不会看到该onload事件。

要解决这个问题,请添加// @run-at document-end到元数据块。

所以脚本变成了:

// ==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);
}
于 2012-12-06T00:09:59.750 回答
3

如果你想要等价于onLoad,它在页面上的所有图像都加载完毕后才会触发,你想// @run-at document-idle在你的元数据块中使用。默认值 document-end 在加载 DOM 时触发,相当于 document.ready。

于 2016-01-10T02:00:40.450 回答
1

你试过用括号调用 examplefunction 吗?:) 像这样:

console.log(exampleFunction());

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

于 2012-12-05T20:41:11.247 回答