When to use "window.onload"?
Asked Answered
G

7

66

In JavaScript, when I want to run a script once when the page has loaded, should I use window.onload or just write the script?

For example, if I want to have a pop-up, should I write (directly inside the <script> tag):

alert("hello!");

Or:

window.onload = function() {
    alert("hello!");
}

Both appear to run just after the page is loaded. What is the the difference?

Gaberones answered 24/11, 2013 at 20:0 Comment(0)
V
58

window.onload just runs when the browser gets to it.

window.addEventListener waits for the window to be loaded before running it.

In general you should do the second, but you should attach an event listener to it instead of defining the function. For example:

window.addEventListener('load', 
  function() { 
    alert('hello!');
  }, false);
Vernavernacular answered 24/11, 2013 at 20:3 Comment(0)
C
86

The other answers all seem out of date

First off, putting scripts at the top and using window.onload is an anti-pattern. It's left over from IE days at best or mis-understandings of JavaScript and the browser at worst.

You can just move your scripts the the bottom of your html

<html>
  <head>
   <title>My Page</title>
  </head> 
  <body>
    content

    <script src="some-external.js"></script>
    <script>
      some in page code
    </script>
  </body>
</html>

The only reason people used window.onload is because they mistakenly believed scripts needed to go in the head section. Because things are executed in order if your script was in the head section then the body and your content didn't yet exist by definition of execute in order.

The hacky workaround was to use window.onload to wait for the rest of the page to load. Moving your script to the bottom also solved that issue and now there's no need to use window.onload since your body and content will have already been loaded.

The more modern solution is to use the defer tag on your scripts but to use that your scripts need to all be external.

<head>
    <script src="some-external.js" defer></script>
    <script src="some-other-external.js" defer></script>
</head>

This has the advantage that the browser will start downloading the scripts immediately and it will execute them in the order specified but it will wait to execute them until after the page has loaded, no need for window.onload or the better but still unneeded window.addEventListener('load', ...

Convalesce answered 15/1, 2018 at 2:20 Comment(9)
why is window.addEventListener better? and would you say that like with window.onload, the only reason people use window.addEventListener('load',... ) . which is unnecessary, is because they don't know you can put the script at the end of body?Bagwig
addEventListener is better than onload because multiple scripts can use it. Only one script csn use onload. Defer is best except that its not supportrd by old browsers. So you can use defer with addEventListener and it will load fastest in new browsers but still load in old ones.Convalesce
Am I the only one that just doesn't like the look of scripts at the end of the page? Sure, referencing external scripts with the defer tag is pretty, but sometimes you just want to put a little bit of script in your page (at the top, dag nab it!), which means that adding an event listener (or falling back to window.onload which, IMHO, is wonderfully simple even with its limitations) is still necessary, so the [old] question is still valid.Pali
You saw scripts at the top 20 years ago using window.onload and now everything looks wrong if it doesn't follow that pattern. I have the opposite bias. When I see code that uses window.onload I think "programmer stuck with old outdated patterns from 20 years ago. You'd be hard pressed to find a modern JavaScript tutorial that uses onload. Pick any modern JavaScript library (react, vue, svelte, three.js, angular, etc) and you won't find them using onload or the load event. Of course do whatever you want. There's no "right" answer.Convalesce
Let me also add though, the load even runs when the page has finished loading, including loading images and iframes. If that's important for your script then maybe you want to use the load event. Most scripts though would like to get started doing whatever they were planning on doing without having to wait for images and iframes to finish.Convalesce
Sometimes you want to run some JS in the head during parsing, but then you want to write some other JS to run only after DOM parsing (DOMContentLoaded). Example: Dark mode toggles. A script in the head usually sets an attribute on the root ASAP, but you have to wait for the page to load so you can grab a ref to your theme toggle and start registering event listeners. If you want to keep these two scripts in sync (e.g., shared variables), addEventListener('DOMContentLoaded', ...) in the head is your best bet. Otherwise, the body script has to access those shared variables under window.x.Wahkuna
(Note that this differs from window.onload since it doesn't have to wait for all content to load. So it's functionally equivalent to putting a script tag at the end of the body or using a deferred script or module script).Wahkuna
Just fyi (you probably know this), while you might make a dark mode toggle with JS, it's certainly possible to just entirely use CSS for dark mode using :root { color-scheme: light dark; ... } and/or @media (prefers-color-scheme: dark) { ... }. For example: code, example which you can toggle from the devtools to see the user's preference video. Of course there might be other reasons you want something to run early.Convalesce
Google Page Speed Insights would like to disagree with you and PSI directly impacts your Organic SEO and Ad Performance. There are loads of legitimate use-cases for window.addEventListener('load', ...) calls. I can show you several examples of window.addEventListener('load', ...) producing at least a 25% higher score than <script defer>Electrolysis
V
58

window.onload just runs when the browser gets to it.

window.addEventListener waits for the window to be loaded before running it.

In general you should do the second, but you should attach an event listener to it instead of defining the function. For example:

window.addEventListener('load', 
  function() { 
    alert('hello!');
  }, false);
Vernavernacular answered 24/11, 2013 at 20:3 Comment(0)
F
8

Here's the documentation on MDN.

According to it:

The load event fires at the end of the document loading process. At this point, all of the objects in the document are in the DOM, and all the images and sub-frames have finished loading.

Your first snippet of code will run as soon as browser hit this spot in HTML.

The second snippet will trigger popup when the DOM and all images are fully loaded (see the specs).

Considering the alert() function, it doesn't really matter at which point it will run (it doesn't depend on anything besides window object). But if you want to manipulate the DOM - you should definitely wait for it to properly load.

Feer answered 24/11, 2013 at 20:5 Comment(1)
@xgqfrms jQuery is not always the answer...Gaberones
S
3

You have three alternatives:

  1. Directly inside the script tag runs it as soon as it is parsed.

  2. Inside document.addEventListener( "DOMContentLoaded", function(){}); will run it once the DOM is ready.

  3. Inside window.onload function(){}) will run as soon as all page resources are loaded.

Softball answered 24/11, 2013 at 20:6 Comment(0)
H
2

That depends on if you want it to run when the script element is encountered or if you want it to run when the load event fires (which is after the entire document (including such things as images) has loaded).

Neither is always right.

In general, however, I'd avoid assigning functions directly to onload in favour of using addEventListener (with compatibility libraries if I needed to support older browsers).

Hamster answered 24/11, 2013 at 20:2 Comment(1)
you write "In general, however, I'd avoid assigning functions directly to onload in favour of using addEventListener" <-- why?Bagwig
M
2

The reason for waiting for the DOM to be loaded is so that you can target any elements that load after your script. If you're just creating an alert, it doesn't matter. Let's say, however, you were targeting a div that was in your markup after your script, you would get an error if you don't wait until that piece of the DOM tree to load.

document.ready is a great alternative to window.onload if you're using jQuery.

See here: window.onload vs $(document).ready()

Mediator answered 24/11, 2013 at 20:5 Comment(0)
O
2

One more interesting difference is that window.onload will only be called once, and it will override the previously attached onload event. But if you use window.addEventListener you can add as many functions as you want, and multiple window.addEventListener won't override each other.

Openandshut answered 10/3, 2023 at 7:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.