How to know if window "load" event was fired already
The easiest solution might be checking for document.readyState == 'complete'
, see http://www.w3schools.com/jsref/prop_doc_readystate.asp
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: What is the non-jQuery equivalent of '$(document).ready()'?
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
- https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState
Complete: The state indicates that the load event is about to fire.
- https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
Gives a live example of event firing ie:
- readyState:
interactive
- Event Fired:
DOMContentLoaded
- readyState:
complete
- 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');
});