Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I run code on DOM ready in Greasemonkey 4?

With the update to Firefox 57 and Greasemonkey 4 a number of my userscripts broke. In some scripts I used:

document.addEventListener('DOMContentLoaded', doStuff, false);

This no longer works in Greasemonkey. What is the proper way to add an DOMContentLoaded event now?

P.S. I checked that at the time of registering the event, DOM is still not ready.

like image 981
jahu Avatar asked Nov 24 '17 23:11

jahu


2 Answers

I still don't know what is the recommended way of running code on DOM ready in Greasemonkey 4, but after changing:

document.addEventListener('DOMContentLoaded', doStuff, false);

to:

window.addEventListener('load', doStuff, false);

my script works again. I just started testing other methods based on this answer, since I noticed that my jQuery based user scripts are still working (at least the DOM ready part does).

This answer is kind of obvious, but at the time of writing the question, I wasn't sure if I was keeping up with the changes in Greasemonkey (reading about all the async stuff) and I expected DOMContentLoaded to just work.

like image 125
jahu Avatar answered Oct 21 '22 18:10

jahu


I ran into a similar problem after GreaseMonkey upgraded to version 4, but I used

addEventListener("DOMContentLoaded", function(){
  // …
});

instead.

When trying to fix my user-scripts, I initially commented out that wrapper and put a

// @run-at document-end

in the metadata block. This way, I ensured that the DOM was ready and the code that was originally inside the DOMContentLoaded wrapper executed correctly.

This worked, however, for two of my user-scripts I actually needed to run JavaScript, before any page script had run and execute other code when the DOM was ready. It turns out, that now you need to put

// @run-at document-start

in the metadata block in order for the DOMContentLoaded wrapper to work on your window (or document).

In previous versions of GreaseMonkey I could just omit this and it would run fine.

However, according to the GreaseSpot Wiki, document-start is not guaranteed to work in GreaseMonkey 4.0, perhaps due to asynchrounous execution or missing features in the WebExtensions rewrite of the add-on.

Also, document.readyState will be "loading" with document-start, but "interactive" with document-end or no // @run-at at all.

like image 25
Sebastian Simon Avatar answered Oct 21 '22 17:10

Sebastian Simon