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

cross-browser, google-chrome, greasemonkey, javascript, userscripts

Solution

The reason that `exampleFunction` was undefined is because Chrome userscripts operate in a sandbox ("isolated world"). Note that Greasemonkey scripts often operate in a sandbox too, but yours is currently running with an implicit `@grant none`. If your script were to use a `GM_` function, it would stop working in Firefox too.

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`. Chrome userscripts, with the default execution start-mode, will often never see the `onload` event.

To get around that, add `// @run-at document-end` to the metadata block.

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);
}

Problem

There is a page http://example.com/1.php that includes javascript file as usual: ``` <script type="text/javascript" src="/util.js?1354729400"></script> ``` This file contain function named exampleFunction which I need to use in my userscript. 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: ``` Uncaught ReferenceError: exampleFunction is not defined ``` How do I make it work?

Original source

Related problems