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

11,065

Solution 1

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

Solution 2

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. The default, document-end, fires when the DOM is loaded, the equivalent of document.ready.

Solution 3

Have you tried calling examplefunction with brackets ? :) Like this:

console.log(exampleFunction());

If you try it in chrome console, you have to add brackets to call function.

Share:
11,065

Related videos on Youtube

Alex
Author by

Alex

Updated on September 16, 2022

Comments

  • Alex
    Alex over 1 year

    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?

  • Stuart
    Stuart over 11 years
    That won't do anything if exampleFunction is really undefined.
  • Alex
    Alex over 11 years
    It's not always working... And I can't determine the reason of that
  • Brock Adams
    Brock Adams over 11 years
    How is it "not working"? What are the symptoms exactly? Use the script from the answer with no changes but the @include line. What is the URL of the page where the script appears not to work? Is that page taking a long time to completely load? onload will not fire until the last large image, etc., has finished downloading.
  • Alex
    Alex over 11 years
    Try it by yourself: remove "console.log(exampleFunction);" and leave "alert" from the script. Staying on this page, click on your profile link and refresh that page several times. How is it working for you? I don't get onload event in half of cases at all
  • Brock Adams
    Brock Adams over 11 years
    @aljesco, I did that and it works every single page load or refresh, without fail. What version of Chrome are you using? What OS? What are your symptoms and error messages? Temporarily disable all other extensions and try again.