Search code examples
javascriptdom-eventsdocument-readydomcontentloaded

window DOMContentLoaded vs document DOMContentLoaded


The modern replacement of the (on)"DOM ready" is the DOMContentLoaded event.

You can listen on it on 2 global objects:

Now I know that the original target of this event is document however according to the MDN link above there's also ability to "listen for this event on the Window interface to handle it in the capture or bubbling phases.".

Is there a particular advantage or a special case when it would be more appropriate or even required to catch the event on the window - for either the capture or the bubble up phase?


Solution

  • I came back to this after some time and it started to make sense:

    1. the Window listener happens AFTER the Document event - because it bubbles FROM the Document

    2. so if you run (jsfiddle):

      window.addEventListener("DOMContentLoaded", (event) => {
        alert("Catching event on window - target: " + event.target.constructor.name);
      });
      

      ...the output in the alert will be:

      Catching event on window - target: HTMLDocument

      Which proves it's from Document since window.constructor.name is "Window"

    This is even described in the Living Standard which reads (as of 2023-06-20)

    13.2.7 The end

    Once the user agent stops parsing the document, the user agent must run the following steps:
    1...
    6. Queue a global task on the DOM manipulation task source given the Document's relevant global object to run the following substeps:

    1. Set the Document's load timing info's DOM content loaded event start time to the current high resolution time given the Document's relevant global object.
    2. Fire an event named DOMContentLoaded at the Document object, with its bubbles attribute initialized to true.
    3. ...

    And also in the Events part of the docs:

    • Event: DOMContentLoaded
    • Interface: Event
    • Interesting targets: Document
    • Description: Fired at the Document once the parser has finished

    There is no mention of DOMContentLoaded for window specifically :-)

    So to answer the main question

    The difference is when you want your handler to be executed.

    1. AFTER ALL document DOMContentLoaded listeners have been executed

      • => use window.addEventListener("DOMContentLoaded", ...
    2. Among all other handlers listening to DOMContentLoaded on Document

      • => use document.addEventListener("DOMContentLoaded", ...

    Sidenote: MDN mentions load event on the "Document: DOMContentLoaded event" page - that is taken out of context and what they mean is to use load event listener on Window - Document does not have a load event since it isn't an Element...