235

What exactly is the difference between the window.onload event and the onload event of the body tag? when do I use which and how should it be done correctly?

Dave Jarvis
  • 28,853
  • 37
  • 164
  • 291
Manu
  • 27,156
  • 27
  • 70
  • 82

13 Answers13

224

window.onload = myOnloadFunc and <body onload="myOnloadFunc();"> are different ways of using the same event. Using window.onload is less obtrusive though - it takes your JavaScript out of the HTML.

All of the common JavaScript libraries, Prototype, ExtJS, Dojo, JQuery, YUI, etc. provide nice wrappers around events that occur as the document is loaded. You can listen for the window onLoad event, and react to that, but onLoad is not fired until all resources have been downloaded, so your event handler won't be executed until that last huge image has been fetched. In some cases that's exactly what you want, in others you might find that listening for when the DOM is ready is more appropriate - this event is similar to onLoad but fires without waiting for images, etc. to download.

Richard Turner
  • 11,186
  • 5
  • 31
  • 37
  • 60
    It should be noted, however, that there is a difference. The inline onload event is going to call `myOnloadFunc()` in the global context (`this` will refer to `window`). Setting it via javascript will make it execute in the context of the element (`this` refers to the element the event was triggered on). In this particular case, it won't make a difference, but it will with other elements. – mowwwalker Mar 19 '12 at 04:22
  • 1
    @Walkerneo: Yep, definitely worth noting. Of course, using a JS library one can override the object that `this` refers to if desired. – Richard Turner Mar 19 '12 at 12:28
  • @RichardTurner You dont need to use a library to change the context binding. A simple .bind() call does that – Kloar Feb 03 '16 at 15:19
  • @Kloar you can these days, yes, but you need MSIE9+. On older MSIE, which was much more common when I answered, you'd need a polyfill. – Richard Turner Feb 03 '16 at 15:25
34

There is no difference, but you should not use either.

In many browsers, the window.onload event is not triggered until all images have loaded, which is not what you want. Standards based browsers have an event called DOMContentLoaded which fires earlier, but it is not supported by IE (at the time of writing this answer). I'd recommend using a javascript library which supports a cross browser DOMContentLoaded feature, or finding a well written function you can use. jQuery's $(document).ready(), is a good example.

ValarDohaeris
  • 5,269
  • 5
  • 25
  • 41
jcampbell1
  • 3,569
  • 3
  • 30
  • 34
  • 55
    Question from the future...What if there's no jquery? – Sid Mar 24 '11 at 15:27
  • 55
    Question from the present.. What if jQuery is overkill for the project at hand? (Not knocking jQuery, use it myself. Just sometimes only want one feature out of a library..) – Bradmage Mar 14 '12 at 08:06
  • 14
    When you say "not supported by IE" is that a universal truth, or only true for specific versions of IE? Since a lot has changed in the browser world since you wrote this answer, maybe it's time to update this answer? – Bryan Oakley May 28 '13 at 16:39
  • 8
    DOMContentLoaded is now supported by IE9 and up: https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded – Adam Mar 25 '15 at 13:18
  • I know this is old, but somehow I ran across it. @BradleyForster I have used DomReady.js seems to work well. Not sure if they have migrated to github yet: https://code.google.com/p/domready/ – Kurtfm Apr 17 '15 at 21:29
  • 6
    Reporting from the future, DOMContentLoaded is now supported by all major browsers: http://caniuse.com/#feat=domcontentloaded – Jose Gómez Apr 25 '16 at 02:31
  • 2
    @Sid There can never be "no jQuery" as it currently exists. You could always host it yourself. Also jcampbell1 How do you know that's not what the OP wants? – Chuck Le Butt Jul 12 '16 at 11:02
  • jQuery is pointless for a few features like this, and anything you can do with it you can do with vanilla JS. – Redwolf Programs May 29 '19 at 22:11
23

window.onload can work without body. Create page with only the script tags and open it in a browser. The page doesn't contain any body, but it still works..

<script>
  function testSp()
  {
    alert("hit");
  }
  window.onload=testSp;
</script>
Kissaki
  • 8,159
  • 4
  • 34
  • 36
john Joseph
  • 231
  • 2
  • 2
  • 6
    HTML without the body tag is invalid if you actually do add content (which should be in a body tag). Also your script tag is missing a type. Never rely on browsers fixing your non-standard-compliant code! (As browsers may do so differently or not at all in the past or future.) – Kissaki Feb 06 '11 at 16:51
  • 4
    @Kissaki: Standard HTML doesn’t need a body tag at all! – Robert Siemer May 29 '13 at 05:35
  • 5
    xhtml1 specifies `` [1] - and html401 specifies `` as well [2]. html51 states `A head element followed by a body element.` for html content as well. [3] http://www.w3.org/TR/xhtml1/dtds.html#a_dtd_XHTML-1.0-Strict http://www.w3.org/TR/xhtml1/dtds.html#a_dtd_XHTML-1.0-Strict http://www.w3.org/TR/html51/semantics.html#the-html-element -- So I guess all of those common/in-use HTML standards *do* require a body tag. :) – Kissaki May 31 '13 at 09:14
  • 1
    @Kissaki that's XHTML, not HTML. HTML allows tag omission of both start and end body tags, as well as omission of html and head tags, as per its SGML DTD. http://www.w3.org/TR/html401/struct/global.html#edef-BODY `Start tag: optional, End tag: optional` – OdraEncoded Nov 20 '14 at 12:16
  • If you want to specifically use HTML4 rather than HTML5, sure. HTML5 would be HTML4 compliant, but not the other way around. So if you really want to code for and only for the last decade, go ahead. – Kissaki Jan 07 '15 at 15:17
  • 1
    @Kissaki: html5 doesn't need the script type anymore (if it's javascript), you're right for earlier versions. – Mark Oct 27 '15 at 21:13
10

I prefer, generally, to not use the <body onload=""> event. I think it's cleaner to keep behavior separated from content as much as possible.

That said, there are occasions (usually pretty rare for me) where using body onload can give a slight speed boost.

I like to use Prototype so I generally put something like this in the <head> of my page:

document.observe("dom:loaded", function(){
  alert('The DOM is loaded!');
});

or

Event.observe(window, 'load', function(){
  alert('Window onload');
});

The above are tricks I learned here. I'm very fond of the concept of attach event handlers outside of the HTML.

(Edit to correct spelling mistake in code.)

Community
  • 1
  • 1
Mark Biek
  • 135,050
  • 52
  • 150
  • 195
  • In what occasions would it be faster, and why? – Kissaki Jan 07 '15 at 15:20
  • This answer seems very subjective with all the “I”s (“I prefer”, “I think”). That if further lacks any objective and verifiable facts pretty much supports that impression. – Kissaki Jan 07 '15 at 15:21
  • 1
    I'd take this answer with a grain of salt considering it was posted over 6 years ago. You're more than welcome to update it or post your own improved answer. – Mark Biek Jan 08 '15 at 13:41
7

'so many subjective answers to an objective question. "Unobtrusive" JavaScript is superstition like the old rule to never use gotos. Write code in a way that helps you reliably accomplish your goal, not according to someone's trendy religious beliefs.

Anyone who finds:

 <body onload="body_onload();">

to be overly distracting is overly pretentious and doesn't have their priorities straight.

I normally put my JavaScript code in a separate .js file, but I find nothing cumbersome about hooking event handlers in HTML, which is valid HTML by the way.

  • 39
    There's good reason for writing unobtrusive javascript. Say you have a web app with 100 pages and you used the method instead of putting it in the javascript file included by every page. Then imagine you needed to change the name of that function for some reason. Putting the event in the included javascript file 1) makes changes vastly simpler, and 2) saves server resources since javascript files can be cached for a year (on a properly configured server) instead of downloading the same code over and over again. – Andrew Ensley Jul 08 '11 at 16:27
  • 21
    So because you don't bother learning why something is recommended you label the recommendations "trendy religious beliefs"?? – hallvors Mar 15 '12 at 12:44
  • 6
    The question is "what is the difference between these two methods?", along with a request for a recommendation for which is better. How does your response answer that question? – Richard Turner Mar 29 '12 at 08:05
  • 1
    Any situation where you make a modular solution in 1 place that can be applied to a large mass of files is far better than adding the code to each of the mass of files itself. It's better for for original build time, code organizational purposes, for readability, and for future editing. It's not trendy, it's actually an older concept that is present in languages like java and c++ that web programmers are now embracing as the far better way to code. – Jimbo Jonny Nov 09 '12 at 18:11
  • 1
    One good defense against XSS attacks in modern browsers is to disable all inline javascript with your Content Security Policy. That's a pretty good reason not to use the onload attribute in your HTML. – Greg Ball Nov 28 '13 at 00:24
4

window.onload - Called after all DOM, JS files, Images, Iframes, Extensions and others completely loaded. This is equal to $(window).load(function() {});

<body onload=""> - Called once DOM loaded. This is equal to $(document).ready(function() {});

fish-404
  • 95
  • 2
  • 14
Yesu Raj
  • 194
  • 1
  • 5
  • 1
    Is someone able to source this? I've seen this statement on many forums but never with a link to where it's defined in the spec. – crempp Jan 02 '14 at 21:58
  • 1
    @crempp There is [The body element](http://www.w3.org/TR/html5/sections.html#the-body-element) and [Global attributes](http://www.w3.org/TR/html5/dom.html#global-attributes), so I would say this is not true. But you can test this yourself, see http://jsbin.com/OmiViPAJ/1/edit. There, you can see the image onload event is fired *before* the body onload event. – Olaf Dietsche Jan 09 '14 at 09:33
  • 2
    This answer contradicts others; can you provide a source? – Jimmy Breck-McKye Apr 21 '14 at 20:35
  • 2
    http://api.jquery.com/ready/ The jQuery docs says: "The .ready() method is generally incompatible with the attribute." I think in jQuery is more close to body.onload $(window).load(..) but I think they still are different. – ccsakuweb Jul 05 '14 at 16:20
  • 2
    This answer is completely wrong and shouldn't have any up votes. In fact this type of answer is generally cited as being among the biggest misconceptions about `ready` vs `onload` events. `load` fires after the entire document is loaded including all scripts, images and stylesheets. `DOMContentLoaded` fires after the DOM tree has been built but before images etc. Its `DOMContentLoaded` that has equivalence to `document.ready`, not `load`. – rism Nov 29 '15 at 01:56
2

There is no difference ...

So principially you could use both (one at a time !-)

But for the sake of readability and for the cleanliness of the html-code I always prefer the window.onload !o]

roenving
  • 2,372
  • 12
  • 14
2

<body onload=""> should override window.onload.

With <body onload=""> , document.body.onload might be null, undefined or a function depending on the browser (although getAttribute("onload") should be somewhat consistent for getting the body of the anonymous function as a string). With window.onload, when you assign a function to it, window.onload will be a function consistently across browsers. If that matters to you, use window.onload.

window.onload is better for separating the JS from your content anyway. There's not much reason to use <body onload=""> ; anyway when you can use window.onload.

In Opera, the event target for window.onload and <body onload=""> (and even window.addEventListener("load", func, false)) will be the window instead of the document like in Safari and Firefox. But, 'this' will be the window across browsers.

What this means is that, when it matters, you should wrap the crud and make things consistent or use a library that does it for you.

fish-404
  • 95
  • 2
  • 14
Shadow2531
  • 11,352
  • 5
  • 29
  • 40
1

If you're trying to write unobtrusive JS code (and you should be), then you shouldn't use <body onload="">.

It is my understanding that different browsers handle these two slightly differently but they operate similarly. In most browsers, if you define both, one will be ignored.

Dr. Bob
  • 534
  • 4
  • 9
1

Think of onload like any other attribute. On an input box, for example, you could put:

<input id="test1" value="something"/>

Or you could call:

document.getElementById('test1').value = "somethingelse";

The onload attribute works the same way, except that it takes a function as its value instead of a string like the value attribute does. That also explains why you can "only use one of them" - calling window.onload reassigns the value of the onload attribute for the body tag.

Also, like others here are saying, usually it is cleaner to keep style and javascript separated from the content of the page, which is why most people advise to use window.onload or like jQuery's ready function.

Soldarnal
  • 6,948
  • 9
  • 44
  • 65
0

They both work the same. However, note that if both are defined, only one of them will be invoked. I generally avoid using either of them directly. Instead, you can attach an event handler to the load event. This way you can incorporate more easily other JS packages which might also need to attach a callback to the onload event.

Any JS framework will have cross-browser methods for event handlers.

KernelM
  • 8,286
  • 2
  • 21
  • 15
0

It is a accepted standard to have content, layout and behavior separate. So window.onload() will be more suitable to use than <body onload=""> though both do the same work.

Rajeshwaran S P
  • 562
  • 1
  • 7
  • 14
0

Sorry for reincarnation of this thread again after another 3 years of sleeping, but perhaps I have finally found the indisputable benefit of window.onload=fn1; over <body onload="fn1()">. It concerns the JS modules or ES modules: when your onload handler resides in "classical" JS file (i.e. referred without <script type="module" … >, either way is possible; when your onload handler resides in "module" JS file (i.e. referred with <script type="module" … >, the <body onload="fn1()"> will fail with "fn1() is not defined" error. The reason perhaps is that the ES modules are not loaded before HTML is parsed … but it is just my guess. Anyhow, window.onload=fn1; works perfectly with modules ...

Petr Pivonka
  • 111
  • 1
  • 2