How to know if window "load" event was fired already

JavascriptAsynchronousDom Events

Javascript Problem Overview


I'm writing a Javascript script. This script will probably be loaded asynchronously (AMD format).

In this script, I'd like to do nothing important until the window.load event was fired. So I listen to the window "load" event.

But if the script is loaded after window.load event... how can I know window.load was already fired?

And of course I don't want to add something in any other scripts (they are all loaded async, the problem is the same) :)

Edit :

Imagine an HTML doc with no Javascript in it at all.

Than someone insert in this doc a

Javascript Solutions


Solution 1 - Javascript

The easiest solution might be checking for document.readyState == 'complete', see http://www.w3schools.com/jsref/prop_doc_readystate.asp

Solution 2 - Javascript

Quick Answer

To quickly answer the question's title:

document.readyState === 'complete'

Deeper Example

Below is a nice helper if you want to call code upon a window load, while still handling the case where the window may have already loaded by the time your code runs.

function winLoad(callback) {
  if (document.readyState === 'complete') {
    callback();
  } else {
    window.addEventListener("load", callback);
  }
}

winLoad(function() {
  console.log('Window is loaded');
});

Note: code snippets on here actually don't run in the same window context so document.readyState === 'complete' actually evaluates to false when you run this. If you put the same into your console right now for this window it should evaluate as true.

See also: https://stackoverflow.com/questions/2304941/what-is-the-non-jquery-equivalent-of-document-ready/53601942#53601942


Handling the Edge Case from @IgorBykov via Comments

Igor brought up an interesting issue in the comments, which the following code can try to handle given a best-effort-timeout.

The problem is that the document.readyState can be complete before the load event fires. I'm not certain what potential problems this may cause.

Some Documentation About the Flow and Event Firing

> Complete: The state indicates that the load event is about to fire.

Gives a live example of event firing ie:

> 1. readyState: interactive > 2. Event Fired: DOMContentLoaded > 3. readyState: complete > 4. Event Fired: load

There's a brief moment where the readyState may be complete before load fires. I'm not sure what issues you may run into during this period.

The below code registers the load event listener, and sets a timeout to check the readyState. By default it will wait 200ms before checking the readyState. If the load event fires before the timeout we make sure to prevent firing the callback again. If we get to the end of the timeout and load wasn't fired we check the readyState and make sure to avoid a case where the load event could potentially still fire at a later time.

Depending on what you're trying to accomplish you may want to run the load callback no matter what (remove the if (!called) { check). In your callback you might want to wrap potential code in a try/catch statement or check for something that you can gate the execution on so that when it calls twice it only performs the work when everything is available that you expect.

function winLoad(callback, timeout = 200) {
  let called = false;

  window.addEventListener("load", () => {
    if (!called) {
      called = true;
      callback();
    }
  });

  setTimeout(() => {
    if (!called && document.readyState === 'complete') {
      called = true;
      callback();
    }
  }, timeout);
}

winLoad(function() {
  console.log('Window is loaded');
});

Solution 3 - Javascript

Browser navigation performance loadEventEnd metric can be used to determinate if load event was triggered:

let navData = window.performance.getEntriesByType("navigation");
if (navData.length > 0 && navData[0].loadEventEnd > 0)
{
    console.log('Document is loaded');
} else {
    console.log('Document is not loaded');
}

Solution 4 - Javascript

If you don't want to use jQuery, the logic it uses is:

if( !document.body )
    setTimeout( checkAgain, 1 );

So between the windows loaded event and checking if the body property of the document is available, you can check if the DOM is ready

Solution 5 - Javascript

Based on @CTS_AE's approach, I have put together a solution for envrionments where:

  • window.addEventListener('load', activateMyFunction); and
  • window.addEventListener('DOMContentLoaded', activateMyFunction);

don't work.

It requires a single character substitution (eg. from

window.addEventListener('load', activateMyFunction);

to

window_addEventListener('load', activateMyFunction);)

The function window_addEventListener() looks like this:

const window_addEventListener = (eventName, callback, useCapture = false) => {

  if ((document.readyState === 'interactive') || (document.readyState === 'complete'))   {

    callback();
  }
}

Solution 6 - Javascript

Easy method:

window.onload = (event) => {
  console.log('page is fully loaded');
};

You can find other methods from resources here.

Solution 7 - Javascript

what about overriding window.load?

window._load = window.load;
window.load = function(){
  window.loaded = true;
  window._load();
}

Then check for

if (window.loaded != undefined && window.loaded == true){
    //do stuff
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNicolasView Question on Stackoverflow
Solution 1 - JavascriptMatthias SamselView Answer on Stackoverflow
Solution 2 - JavascriptCTS_AEView Answer on Stackoverflow
Solution 3 - JavascriptEvgenyView Answer on Stackoverflow
Solution 4 - JavascriptMatt R. WilsonView Answer on Stackoverflow
Solution 5 - JavascriptRounin - Standing with UkraineView Answer on Stackoverflow
Solution 6 - JavascriptAMMAR ELHAMDOView Answer on Stackoverflow
Solution 7 - JavascriptEric FrickView Answer on Stackoverflow