91

It doesn't give an error, and I put a console.log('loaded userscript wifi-autologin'), the console.log works, but the intended effect of the document.addEventListener doesn't happen. After doing a bit more debugging, making it print that the addEventListener was called, I discovered that it wasn't being called.

Source of script:

// ==UserScript== // @name wifi-autologin // @namespace lf-ns // @description Hopefully autologins to a captive portal // @include *://1.1.1.1/* // @version 1 // @run-at document-end // ==/UserScript== document.addEventListener('load', submitAction); 
5
  • 15
    Listen for the load event on window. Commented May 6, 2013 at 17:57
  • 3
    You mean window.addEventListener()? Commented May 6, 2013 at 17:58
  • Yep, although both work ( see jsbin.com/aqoweb/1 ), I find using window is much more reliable. Commented May 6, 2013 at 18:13
  • 1
    @PaulS. From what I can see in the pastebin you linked, all addEventListeners are being appended to window (even the one which is meant to be hooked to document as the comment in the code and the message in the console says). There's no document.addEventListener('load' ... in the source code :-/ Commented Sep 27, 2015 at 18:12
  • I agree @david.binda, the example of Paul S. does not test document event handlers. just window ones. Commented Oct 22, 2015 at 13:17

6 Answers 6

135

Apparently, document.addEventListener() is unreliable, and hence, my error. Use window.addEventListener() with the same parameters, instead.

Sign up to request clarification or add additional context in comments.

7 Comments

How did you get to the conclusion of that document.addEventListener('load',...) is unreliable?
I had already seen the comment saying "Listen for the load event on window" and the jsfiddle I did confirms it works. But the thing is, why is it not working on document? According to the documentation I wrote on my response it should work. So what I wanted to know is if you understood why it is not working on document.
@AlexMM I have no idea. I have decided that it's just gremlins.
Bad news then. The funny thing is that the event DOMContentLoaded does fire on document, and it is an event previous to load event so it is weird why one is fired and the other not.
in chrome, I'm getting document 'load' event to fire if i set the useCapture option to true. However, it's firing twice; more gremlins?
|
15

To get the value of my drop down box on page load, I use

document.addEventListener('DOMContentLoaded',fnName); 

Hope this helps some one.

1 Comment

DOMContentLoaded is not a load event. It means that the DOM is ready but it is not always triggered after all your ressources (images, css files or js files) are done loaded.
15

According to HTML living standard specification, the load event is

Fired at the Window when the document has finished loading; fired at an element containing a resource (e.g. img, embed) when its resource has finished loading

I.e. load event is not fired on document object.

Credit: Why does document.addEventListener(‘load’, handler) not work?

1 Comment

The second link is broken
13

For rookies like me, the top voted answer is not correct. document.addEventListener() is not perfect but it is reliable.

The simple answer document.addEventListener('load', function) doesn't work is because the load event fires on the window, not the document.

See the documentation here - https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event

window.addEventListener('load', runsWhenReady); //✅ load fires on the window and works. document.addEventListener('DOMContentLoaded', runsWhenReady); //✅ domcontent fires on the document and works document.addEventListener('load', runsWhenReady); //🚫 this WILL NOT work. load doesn't fire on the document. 

Comments

9

The problem is WHEN the event is added and EXECUTED via triggering (the document onload property modification can be verified by examining the properties list).

When does this execute and modify onload relative to the onload event trigger:

document.addEventListener('load', ... ); 

before, during or after the load and/or render of the page's HTML?
This simple scURIple (cut & paste to URL) "works" w/o alerting as naively expected:

data:text/html;charset=utf-8, <html content editable><head> <script> document.addEventListener('load', function(){ alert(42) } ); </script> </head><body>goodbye universe - hello muiltiverse</body> </html> 

Does loading imply script contents have been executed?

A little out of this world expansion ...
Consider a slight modification:

data:text/html;charset=utf-8, <html content editable><head> <script> if(confirm("expand mind?"))document.addEventListener('load', function(){ alert(42) } ); </script> </head><body>goodbye universe - hello muiltiverse</body> </html> 

and whether the HTML has been loaded or not.

Rendering is certainly pending since goodbye universe - hello muiltiverse is not seen on screen but, does not the confirm( ... ) have to be already loaded to be executed? ... and so document.addEventListener('load', ... ) ... ?

In other words, can you execute code to check for self-loading when the code itself is not yet loaded?

Or, another way of looking at the situation, if the code is executable and executed then it has ALREADY been loaded as a done deal and to retroactively check when the transition occurred between not yet loaded and loaded is a priori fait accompli.

So which comes first: loading and executing the code or using the code's functionality though not loaded?

onload as a window property works because it is subordinate to the object and not self-referential as in the document case, ie. it's the window's contents, via document, that determine the loaded question err situation.

PS.: When do the following fail to alert(...)? (personally experienced gotcha's):

caveat: unless loading to the same window is really fast ... clobbering is the order of the day
so what is really needed below when using the same named window:

window.open(URIstr1,"w") . addEventListener('load', function(){ alert(42); window.open(URIstr2,"w") . addEventListener('load', function(){ alert(43); window.open(URIstr3,"w") . addEventListener('load', function(){ alert(44); /* ... */ } ) } ) } ) 

alternatively, proceed each successive window.open with:
alert("press Ok either after # alert shows pending load is done or inspired via divine intervention" );

data:text/html;charset=utf-8, <html content editable><head><!-- tagging fluff --><script> window.open( "data:text/plain, has no DOM or" ,"Window" ) . addEventListener('load', function(){ alert(42) } ) window.open( "data:text/plain, has no DOM but" ,"Window" ) . addEventListener('load', function(){ alert(4) } ) window.open( "data:text/html,<html><body>has DOM and", "Window" ) . addEventListener('load', function(){ alert(2) } ) window.open( "data:text/html,<html><body>has DOM and", "noWindow" ) . addEventListener('load', function(){ alert(1) } ) /* etc. including where body has onload=... in each appropriate open */ </script><!-- terminating fluff --></head></html> 

which emphasize onload differences as a document or window property.

Another caveat concerns preserving XSS, Cross Site Scripting, and SOP, Same Origin Policy rules which may allow loading an HTML URI but not modifying it's content to check for same. If a scURIple is run as a bookmarklet/scriplet from the same origin/site then there maybe success.

ie. From an arbitrary page, this link will do the load but not likely do alert('done'):

 <a href="javascript:window.open('view-source:http://google.ca') . addEventListener( 'load', function(){ alert('done') } )"> src. vu </a> 

but if the link is bookmarked and then clicked when viewing a google.ca page, it does both.

test environment:

 window.navigator.userAgent = Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.4) Gecko/2008102920 Firefox/3.0.4 (Splashtop-v1.2.17.0) 

Comments

0

this happened again around last quarter of 2017 . greasemonkey firing too late . after domcontentloaded event already been fired.

what to do:

  • i used @run-at document-start instead of document-end
  • updated firefox to 57.

from : https://github.com/greasemonkey/greasemonkey/issues/2769

Even as a (private) script writer I'm confused why my script isn't working.

The most likely problem is that the 'DOMContentLoaded' event is fired before the script is run. Now before you come back and say @run-at document-start is set, that directive isn't fully supported at the moment. Due to the very asynchronous nature of WebExtensions there's little guarantee on when something will be executed. When FF59 rolls around we'll have #2663 which will help. It'll actually help a lot of things, debugging too.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.