787

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

Kamil Kiełczewski
  • 53,729
  • 20
  • 259
  • 241
Chris Ballance
  • 32,056
  • 25
  • 101
  • 147
  • 3
    MDN docs explains these `window` events: `onload` and `DOMContentLoaded`. Usage example:, `window.addEventListener('DOMContentLoaded', callback)`. As of mid 2019, compatible with all major browsers. ----- https://developer.mozilla.org/en-US/docs/Web/API/Window/DOMContentLoaded_event ------ https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event – Craig Hicks Jul 08 '19 at 09:32
  • **For me even still, in Firefox 75.0 today, `window.onload` and `document.onload` are *different* from each other!** `window.onload` seems to take place afterwards and has a bit more loaded than `document.onload`! (Some things are working with window that aren't working with document! That goes for document.onreadstatechange 'complete' as well!) – Andrew Apr 24 '20 at 16:33

9 Answers9

795

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.

daaawx
  • 2,268
  • 2
  • 12
  • 13
Josh Mein
  • 26,372
  • 12
  • 72
  • 84
  • 26
    Actually that statement seems to be directed at a choice between `window.onload` and `` which is completely different (and the "separate structure from action" makes a lot more sense in this context). Not that the answer is wrong, but the basis of it is. – Thor84no Sep 17 '12 at 10:39
  • 2
    That quote is grammatically horrible... shouldn't some (marked) editing help? – Kheldar Jan 16 '13 at 15:43
  • @Thor84no I finally found the time to look take another look at this. I have made a few improvements. – Josh Mein Sep 23 '13 at 14:04
  • @Kheldar I decided to paraphrase the quote since it was rather rough. – Josh Mein Sep 23 '13 at 14:04
  • @JoshMein Does it mean that `document.onload` is JS-equivalent of jQuery `document.ready`? – john c. j. Feb 14 '17 at 15:22
  • Does the onload event waits for xhr reqests ? – Jeyenth Sep 18 '17 at 13:33
  • @JeyenthaaranNanjappan It does not wait for xhr requests. – Josh Mein Sep 18 '17 at 14:21
  • @JeyenthaaranNanjappan XHR components have a `readystatechange` event that fires at 5 different stages in the operation (codes of 0-4). 4 represents that the response was received back from the server. – Scott Marcus Sep 21 '17 at 18:31
  • I think this answer needs some updates. On MDN now it's classified merely into `DOMContentLoaded` and `load` events. I don't see the differences between `document` and `window` prefix as this answer describes. Check the links of the first comment under the question. – Rick Jul 28 '20 at 02:29
  • Wow, this answer really has gotten a lot of (editing) love over the years! Thank you for keeping it pretty. – lmat - Reinstate Monica May 12 '21 at 19:18
287

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.

Lorenz Lo Sauer
  • 20,692
  • 12
  • 75
  • 85
178

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.
Aakash
  • 14,077
  • 4
  • 77
  • 63
  • 19
    "The DOMContentLoaded event is fired when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading." - https://developer.mozilla.org/en/docs/Web/Events/DOMContentLoaded So you seem to be incorrect about everything being loaded at this event. – ProfK Mar 29 '17 at 08:11
  • 2
    @ProfK, thank you for your feedback. Can you try `window.addEventListener('load', function() {...})`. I've also updated my answer. – Aakash Mar 30 '17 at 00:03
  • 6
    What I like about this answer is that it gives a plain-old-javascript solution. You'd think that most people think jQuery is built into all browsers, given how often it is given as the only answer. – Dave Land Aug 24 '18 at 21:27
  • Double problem when the damn jquery takes too long to load and you get $ not found. I'm of the opinion that the $(window).ready type solutions should NEVER be trusted to work. – Shayne Sep 13 '18 at 14:10
  • 1
    I've tried both in todays chrome. It's not waiting for css and fonts. – movAX13h Oct 10 '18 at 15:10
91

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
};
Oriol
  • 225,583
  • 46
  • 371
  • 457
  • I ran your snippet and `document - load - capture` does indeed happen, which is counter to what I was expecting in my search as to why document load isn't happening for me. Bizarrely, it is inconsistent. Sometimes it appears, sometimes it doesn't, sometimes it appears twice - but never does a `document - load - bubble` happen. I would suggest not using `document load`. – erroric Aug 31 '16 at 20:36
  • @erroric Good point. I didn't consider that a `load` event is dispatched on external resources. That event does not bubble so it's not usually detected on the document, but it should in the capture phase. These entries refer to the load of the ` – Oriol Aug 31 '16 at 21:19
  • Thanks Oriol, the `useCapture` option taught me something new. – Paul Watson Feb 19 '20 at 16:09
  • Thanks for summarizing the parsing and rendering flow from w3. I just wonder after step 4 once ‘load’ event is fired, what else can happen? I noticed on my browser that sometimes there are still some objects being fetched after load event is fired although I haven’t touched or interacted with the page at all. Do you know what are those objects called? ‘Non-blocking rendering objects? – weefwefwqg3 Apr 27 '20 at 04:43
13

In Chrome, window.onload is different from <body onload="">, whereas they are the same in both Firefox(version 35.0) and IE (version 11).

You could explore that by the following snippet:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <!--import css here-->
        <!--import js scripts here-->

        <script language="javascript">

            function bodyOnloadHandler() {
                console.log("body onload");
            }

            window.onload = function(e) {
                console.log("window loaded");
            };
        </script>
    </head>

    <body onload="bodyOnloadHandler()">

        Page contents go here.

    </body>
</html>

And you will see both "window loaded"(which comes firstly) and "body onload" in Chrome console. However, you will see just "body onload" in Firefox and IE. If you run "window.onload.toString()" in the consoles of IE & FF, you will see:

"function onload(event) { bodyOnloadHandler() }"

which means that the assignment "window.onload = function(e)..." is overwritten.

VincentZHANG
  • 727
  • 1
  • 10
  • 28
9

window.onload and onunload are shortcuts to document.body.onload and document.body.onunload

document.onload and onload handler on all html tag seems to be reserved however never triggered

'onload' in document -> true

Hamed Ali Khan
  • 1,086
  • 3
  • 21
  • 28
garaboncias
  • 181
  • 1
  • 3
5

window.onload however they are often the same thing. Similarly body.onload becomes window.onload in IE.

AnthonyWJones
  • 178,910
  • 32
  • 227
  • 302
1

Window.onload is the standard, however - the web browser in the PS3 (based on Netfront) doesn't support the window object, so you can't use it there.

gotofritz
  • 3,184
  • 28
  • 45
1

In short

  • window.onload is not supported by IE 6-8
  • document.onload is not supported by any modern browser (event is never fired)

window.onload   = () => console.log('window.onload works');   // fired
document.onload = () => console.log('document.onload works'); // not fired
Kamil Kiełczewski
  • 53,729
  • 20
  • 259
  • 241