window.onload vs document.onload

Which is more widely supported: window.onload or document.onload?


Solution 1:

When do they fire?

window.onload

  • By default, it is fired when the entire page loads, including its content (images, CSS, scripts, etc.).

In some browsers it now takes over the role of document.onload and fires when the DOM is ready as well.

document.onload

  • It is called when the DOM is ready which can be prior to images and other external content is loaded.

How well are they supported?

window.onload appears to be the most widely supported. In fact, some of the most modern browsers have in a sense replaced document.onload with window.onload.

Browser support issues are most likely the reason why many people are starting to use libraries such as jQuery to handle the checking for the document being ready, like so:

$(document).ready(function() { /* code here */ });
$(function() { /* code here */ });

For the purpose of history. window.onload vs body.onload:

A similar question was asked on codingforums a while back regarding the usage of window.onload over body.onload. The result seemed to be that you should use window.onload because it is good to separate your structure from the action.

Solution 2:

The general idea is that window.onload fires when the document's window is ready for presentation and document.onload fires when the DOM tree (built from the markup code within the document) is completed.

Ideally, subscribing to DOM-tree events, allows offscreen-manipulations through Javascript, incurring almost no CPU load. Contrarily, window.onload can take a while to fire, when multiple external resources have yet to be requested, parsed and loaded.

►Test scenario:

To observe the difference and how your browser of choice implements the aforementioned event handlers, simply insert the following code within your document's - <body>- tag.

<script language="javascript">
window.tdiff = []; fred = function(a,b){return a-b;};
window.document.onload = function(e){ 
    console.log("document.onload", e, Date.now() ,window.tdiff,  
    (window.tdiff[0] = Date.now()) && window.tdiff.reduce(fred) ); 
}
window.onload = function(e){ 
    console.log("window.onload", e, Date.now() ,window.tdiff, 
    (window.tdiff[1] = Date.now()) && window.tdiff.reduce(fred) ); 
}
</script>

►Result:

Here is the resulting behavior, observable for Chrome v20 (and probably most current browsers).

  • No document.onload event.
  • onload fires twice when declared inside the <body>, once when declared inside the <head> (where the event then acts as document.onload ).
  • counting and acting dependent on the state of the counter allows to emulate both event behaviors.
  • Alternatively declare the window.onload event handler within the confines of the HTML-<head> element.

►Example Project:

The code above is taken from this project's codebase (index.html and keyboarder.js).


For a list of event handlers of the window object, please refer to the MDN documentation.

Solution 3:

Add Event Listener

<script type="text/javascript">
  document.addEventListener("DOMContentLoaded", function(event) {
      /* 
        - Code to execute when only the HTML document is loaded.
        - This doesn't wait for stylesheets, 
          images, and subframes to finish loading. 
      */
  });
</script>

Update March 2017

1 Vanilla JavaScript

window.addEventListener('load', function() {
    console.log('All assets are loaded')
})

2 jQuery

$(window).on('load', function() {
    console.log('All assets are loaded')
})

Good Luck.

Solution 4:

According to Parsing HTML documents - The end,

  1. The browser parses the HTML source and runs deferred scripts.

  2. A DOMContentLoaded is dispatched at the document when all the HTML has been parsed and have run. The event bubbles to the window.

  3. The browser loads resources (like images) that delay the load event.

  4. A load event is dispatched at the window.

Therefore, the order of execution will be

  1. DOMContentLoaded event listeners of window in the capture phase
  2. DOMContentLoaded event listeners of document
  3. DOMContentLoaded event listeners of window in the bubble phase
  4. load event listeners (including onload event handler) of window

A bubble load event listener (including onload event handler) in document should never be invoked. Only capture load listeners might be invoked, but due to the load of a sub-resource like a stylesheet, not due to the load of the document itself.

window.addEventListener('DOMContentLoaded', function() {
  console.log('window - DOMContentLoaded - capture'); // 1st
}, true);
document.addEventListener('DOMContentLoaded', function() {
  console.log('document - DOMContentLoaded - capture'); // 2nd
}, true);
document.addEventListener('DOMContentLoaded', function() {
  console.log('document - DOMContentLoaded - bubble'); // 2nd
});
window.addEventListener('DOMContentLoaded', function() {
  console.log('window - DOMContentLoaded - bubble'); // 3rd
});

window.addEventListener('load', function() {
  console.log('window - load - capture'); // 4th
}, true);
document.addEventListener('load', function(e) {
  /* Filter out load events not related to the document */
  if(['style','script'].indexOf(e.target.tagName.toLowerCase()) < 0)
    console.log('document - load - capture'); // DOES NOT HAPPEN
}, true);
document.addEventListener('load', function() {
  console.log('document - load - bubble'); // DOES NOT HAPPEN
});
window.addEventListener('load', function() {
  console.log('window - load - bubble'); // 4th
});

window.onload = function() {
  console.log('window - onload'); // 4th
};
document.onload = function() {
  console.log('document - onload'); // DOES NOT HAPPEN
};