0

I have seen many times (for example: SO) on SO where people attach a load event listener via document, like:

document.addEventListener("load", function(){
  console.log("Loaded.");
});

I can't get it. Am I right in thinking that this is not a correct use? And the proper way of using the load event is through the window only:

window.addEventListener("load", function () {
  console.log("Loaded.");
});

Here's a simple example I tried (FF, Chrome) and it didn't work:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script>
    document.addEventListener("load", function(){
      console.log("Hello world!");
    });
  </script>
</head>
<body>
  <h1>This is a page title</h1>
</body>
</html>

Thanks in advance!

Incognito
  • 41
  • 1
  • 5
  • 1
    https://stackoverflow.com/questions/16404380/why-doesnt-document-addeventlistenerload-function-work-in-a-greasemonkey-s – deekep Aug 13 '23 at 23:49
  • 1
    **document** - It's loaded after the loading window because the window contains a document. **window** - It's loaded before the document because window container document. Either way is correct. – Newbee Aug 13 '23 at 23:55
  • Note that you can do this _entirely automatically_ without any event listeners at all. Load your script with `` and your script will now load in parallel to the page itself (so it won't block anything), and it will _run_ only once the initial DOM is ready. And even though IE no longer exists, this even worked in IE =) – Mike 'Pomax' Kamermans Aug 14 '23 at 00:29
  • @Mike'Pomax'Kamermans yeah, I know, thank you. I am just curious, does it work with `document` or not, because many people on SO use it with `document` – Incognito Aug 14 '23 at 00:35
  • And what year are they doing that in? Because in 2023 there is literally no reason to use a load event listener (though to be fair, even in 2018 there was literally no reason to use a load event listener. The only counter woudl be "but my script is inline" to which the proper response is "then move it into its own file, where it belongs", for reasons ranging from caching to security =) – Mike 'Pomax' Kamermans Aug 14 '23 at 03:21

1 Answers1

0

Page Load Events

The "load" event fires when the page is completely loaded and is commonly registered to the Window Object. External resources such as <img> can also be registered to the "load" event as well as <link> and <script>.

The "DOMContentLoaded" event fires when the HTML is loaded and the DOM tree is parsed. Only the Document Object can be registered to this event. Unlike the "load" event, external resources like <img>, <link>, and <script> are not loaded yet.

Although "DOMContentLoaded" should fire first, there may be a "load" event that fires before "DOMContentloaded" by hairline difference of 1ms, see this post for details.

In order to handle "load" event on <link> or <script>, they must be dynamically added to the DOM. (see Example).

Example

document.addEventListener("DOMContentLoaded", logEvent);
window.addEventListener("load", logEvent);

let href = "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css";
let src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.0/jquery.min.js";

const link = loadLink(href);
const script = loadScript(src);
const img = document.images[0];

link.addEventListener("load", logEvent);
script.addEventListener("load", logEvent);
img.addEventListener("load", logEvent);

function loadLink(url) {
  const link = document.createElement("link");
  link.href = url;
  link.rel = "stylesheet";
  document.head.append(link);
  return link;
}

function loadScript(url) {
  const script = document.createElement("script");
  script.src = url;
  document.body.append(script);
  return script;
}

function logEvent(event) {
  const node = event.currentTarget;
  let object = node == `[object HTMLDocument]` ? "DOCUMENT" : node == `[object Window]` ? "WINDOW" : node.tagName;
  console.log(`${event.type} on ${object} - ${Date.now()}`);
}
:root {
  width: 100%;
  font: 5vmin/1 "Segoe UI";
}

body {
  position: relative;
  width: 100%;
}

main {
  width: 96vw;
}

h1 {
  position: absolute;
  z-index: 1;
  padding: 0.5rem;
  color: white;
}

img {
  width: 100%;
  object-fit: cover;
}

.as-console-row::after {
  width: 0;
  font-size: 0;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title></title>
</head>

<body>
  <main>
    <h1>Page Load Events <i class="fa-solid fa-spinner fa-spin"></i></h1>
    <img src="https://images.unsplash.com/photo-1543373014-cfe4f4bc1cdf?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1000&q=80">
  </main>
</body>

</html>
zer00ne
  • 41,936
  • 6
  • 41
  • 68