Page event listeners: DOMContentLoaded, load, beforeunload and unload

OpenJavaScript 0
Reading Time: 4 minutes 🕑

Last updated: February 14, 2022.

Sometimes we want some code to run only when a page has reached a certain state of loading (e.g. the DOM has loaded or all resources have loaded) or when a user is exiting the page.

We can achieve this by listening out for events on the global window object. In this tutorial, look at four such events: DOMContentLoaded, load, beforeunload, unload.

Page states

When a page loads, it goes through several states.

We can see the initial state of a page by logging the value of the readyState property on the document object. And we can see state changes by listening out for the readystatechange event on the document object:

// Log initial state:
console.log(document.readyState);

// Log changes to state as page loads:
document.addEventListener('readystatechange', () => console.log(document.readyState));

// Output:
// (1) loading
// (2) interactive
// (3) complete

This produces three values. Each is fired as a page reaches different states in its loading:

  1. loading: The page is in an initial state of loading
  2. interactive: The content of the DOM has loaded
  3. complete: Resources are loaded (image sizes are known, scripts, stylesheets, etc.)

Event listeners that run some code only after a page has reached a certain state of loading are related to these events.

The DOMContentLoaded event is triggered once the page becomes interactive. The load event occurs after the loading of all resources is complete, including the full loading of images. This means it occurs after the value of document.readyState changes to complete because this happens when image sizes are known.

We can see this process by logging the values document.readyState and something for both the DOMContentLoaded and load events:

// Log initial state:
console.log(document.readyState);

// Log changes to state as page loads:
document.addEventListener('readystatechange', () => console.log(document.readyState));

// Log when DOMContentLoaded event occurs:
window.addEventListener('DOMContentLoaded', () => console.log("DOM content loaded"));

// Log when load event occurs:
window.addEventListener('load', () => (console.log("All resources loaded)));

// Output:
// (1) loading
// (2) interactive
// (3) DOM content loaded
// (4) complete
// (5) All resources loaded

Page events

DOMContentLoaded

You can run some code only once the content of the DOM has loaded by listening out for the DOMContentLoaded event on the global window object.

This can be useful is you are trying to manipulate DOM elements and want to be sure they are fully parsed.

window.addEventListener('DOMContentLoaded', (event) => {
    alert("DOM ready!");
});

load

The load event on the window object is fired once the DOM and all resources, such as images and scripts, have loaded.

One example where waiting for loading over DOMContentLoaded makes sense is if you have a loading screen, and only want to reveal the full page to the user once everything is ready.

window.addEventListener('load', (event) => {
    alert("All resources loaded!");
});

beforeunload

The beforeunload event on the window object presents a chance to warn a user before leaving the page. It is triggered if a user tries to close the window, navigate to another page or refresh the page.

It only fires if a returnValue is set for the event parameter. But, ironically, most browsers override this message with a default message. In Chrome and Edge, the default message is "Leave Site? Changes you made may not be saved". A default message is used to prevent the user from being deceived to remain on the page.

Also note that in most browsers, the beforeunload event only fires if a user has interacted with the page. This is because it is primarily intended to warn users that unsaved changes may be lost.

window.addEventListener('beforeunload', (event) => {
  event.returnValue = `Leaving already?`;
  /* Note: this message is ignored by most browsers 
           and a default message shown instead      */
});

unload

The unload event is fired when a user exits a page.

Understandably, browsers severely limit what can be done in response to this event.

But there is an important use that is not prevented by browsers: the navigator.sendBeacon method, available on the window object, which can be used to make a POST request to a same-origin API. This is typically used to save session data.

The unload event works by passing its function to the browser. The browser then executes this asynchronously when it can do so without blocking user navigation.

let sessionData = { data };
window.addEventListener("unload", function() {
  navigator.sendBeacon("/api", JSON.stringify(sessionData));
});

Summary

Sometimes we want some code to run only when a page has reached a certain state of loading (e.g. the DOM has loaded or all resources have loaded) or when a user is exiting the page.

We can listen out for these events by attaching event listeners to the global window object:

EventWhen?
DOMContentLoadedThe DOM has loaded
loadedAll resources have loaded
beforeunloadA user attempts to leave the page
unloadA user is leaving the page