window.onload works in Firefox+Greasemonkey script but not in a Chrome userscript?
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.
Related videos on Youtube
Alex
Updated on September 16, 2022Comments
-
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 over 11 yearsThat won't do anything if exampleFunction is really undefined.
-
Alex over 11 yearsIt's not always working... And I can't determine the reason of that
-
Brock Adams over 11 yearsHow 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 over 11 yearsTry 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 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.