How to make JavaScript execute after page load?

1,949,834

Solution 1

These solutions will work:

As mentioned in comments use defer:

<script src="deferMe.js" defer></script>

or

<body onload="script();">

or

document.onload = function ...

or even

window.onload = function ...

Note that the last option is a better way to go since it is unobstrusive and is considered more standard.

Solution 2

Triggering scripts in the right moment

A quick overview on how to load / run the script at the moment in which they intend to be loaded / executed.

Using "defer"

<script src="script.js" defer></script>

Using defer will trigger after domInteractive (document.readyState = "interactive") and just before "DOMContentLoaded" Event is triggered. If you need to execute the script after all resources (images, scripts) are loaded use "load" event or target one of the document.readyState states. Read further down for more information about those events / states, as well as async and defer attributes corresponding to script fetching and execution timing.

This Boolean attribute is set to indicate to a browser that the script is meant to be executed after the document has been parsed, but before firing DOMContentLoaded.

Scripts with the defer attribute will prevent the DOMContentLoaded event from firing until the script has loaded and finished evaluating.

Resource: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attributes

* See the images at the bottom for feather explanation.

Event Listeners - Keep in mind that loading of the page has more, than one event:

"DOMContentLoaded"

This event is fired when the initial HTML document has been completely loaded and parsed, without waiting for style sheets, images, and subframes to finish loading. At this stage you could programmatically optimize loading of images and CSS based on user device or bandwidth speed.

Executes after DOM is loaded (before images and CSS):

document.addEventListener("DOMContentLoaded", function(){
    //....
});

Note: Synchronous JavaScript pauses parsing of the DOM. If you want the DOM to get parsed as fast as possible after the user requested the page, you could turn your JavaScript asynchronous and optimize loading of style sheets

"load"

A very different event, **load**, should only be used to detect a *fully-loaded page*. It is an incredibly popular mistake to use load where DOMContentLoaded would be much more appropriate, so be cautious.

Executes after everything is loaded and parsed:

document.addEventListener("load", function(){
    // ....
});

MDN Resources: https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded https://developer.mozilla.org/en-US/docs/Web/Events/load

MDN list of all events:
https://developer.mozilla.org/en-US/docs/Web/Events

Event Listeners with radyStates - Alternative solution (readystatechange):

You can also track document.readystatechange states to trigger script execution.
// Place in header (do not use async or defer)
document.addEventListener('readystatechange', event => {
  switch (document.readyState) {
    case "loading":
      console.log("document.readyState: ", document.readyState,
       `- The document is still loading.`
       );
      break;
    case "interactive":
      console.log("document.readyState: ", document.readyState, 
        `- The document has finished loading DOM. `,
        `- "DOMContentLoaded" event`
        );
      break;
    case "complete":
      console.log("document.readyState: ", document.readyState, 
        `- The page DOM with Sub-resources are now fully loaded. `,
        `- "load" event`
        );
      break;
  }
});

MDN Resources: https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState

Where to place your script (with & without async/defer)?

This is also very important to know where to place your script and how it positions in HTML as well as parameters like defer and async will affects script fetching, execution and HTML blocking.

* On the image below the yellow label “Ready” indicates the moment of ending loading HTML DOM. Then it fires: document.readyState = "interactive" >>> defered scripts >>> DOMContentLoaded event (it's sequential);

enter image description here

enter image description here

enter image description here

enter image description here

If your script uses async or defer read this: https://flaviocopes.com/javascript-async-defer/

Solution 3

Reasonably portable, non-framework way of having your script set a function to run at load time:

if(window.attachEvent) {
    window.attachEvent('onload', yourFunctionName);
} else {
    if(window.onload) {
        var curronload = window.onload;
        var newonload = function(evt) {
            curronload(evt);
            yourFunctionName(evt);
        };
        window.onload = newonload;
    } else {
        window.onload = yourFunctionName;
    }
}

Solution 4

You can put a "onload" attribute inside the body

...<body onload="myFunction()">...

Or if you are using jQuery, you can do

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

or 

$(window).load(function(){ /*code here*/ })

I hope it answer your question.

Note that the $(window).load will execute after the document is rendered on your page.

Solution 5

If the scripts are loaded within the <head> of the document, then it's possible use the defer attribute in script tag.

Example:

<script src="demo_defer.js" defer></script>

From https://developer.mozilla.org:

defer

This Boolean attribute is set to indicate to a browser that the script is meant to be executed after the document has been parsed, but before firing DOMContentLoaded.

This attribute must not be used if the src attribute is absent (i.e. for inline scripts), in this case it would have no effect.

To achieve a similar effect for dynamically inserted scripts use async=false instead. Scripts with the defer attribute will execute in the order in which they appear in the document.

Share:
1,949,834
Robin Rodricks
Author by

Robin Rodricks

Updated on December 08, 2021

Comments

  • Robin Rodricks
    Robin Rodricks over 2 years

    I'm executing an external script, using a <script> inside <head>.

    Now since the script executes before the page has loaded, I can't access the <body>, among other things. I'd like to execute some JavaScript after the document has been "loaded" (HTML fully downloaded and in-RAM). Are there any events that I can hook onto when my script executes, that will get triggered on page load?

  • Robin Rodricks
    Robin Rodricks about 15 years
    Is this event reliable? (Cross browser.. IE6+ FF2+ etc)
  • Daniel A. White
    Daniel A. White about 15 years
    Yes this is cross-browser, standard DOM.
  • Peter Bailey
    Peter Bailey about 15 years
    It's actually window.onload that's more standard, not document.onload. AFAIK
  • Pyro
    Pyro about 15 years
    +1 for posting almost exactly what I had to come up with 6 months ago. Code like this can be necessary if other frameworks and code that you have no control over are adding onload events and you want to as well without wiping out the other onload events. I included my implementation as a function and it required var newonload = function(evt) { curronload(evt); newOnload(evt); } because for some reason the framework I am using requires an event to be passed to the onload event.
  • Pyro
    Pyro about 15 years
    I just discovered in testing that the code as written results in handlers being fired in an undefined order when attached with attachEvent(). If order-of-handler-execution is important you may want to leave out the window.attachEvent branch.
  • Mentoliptus
    Mentoliptus over 12 years
    What is the difference between <body onload="script();"> and document.onload=function ... ?
  • marcgg
    marcgg over 12 years
    @mentoliptus: document.onload= is non obtrusive en.wikipedia.org/wiki/Unobtrusive_JavaScript
  • Admin
    Admin over 10 years
    script in the html ...no no no $(function() { code here }); <- javascript.js can be placed in head and will load after DOM
  • marcgg
    marcgg over 10 years
    @gerdi OP didn't mention anything about jQuery. I also gave an unobtrusive option in my answer.
  • marcgg
    marcgg over 10 years
    @gerdi No problem, I edited my answer to show the difference more clearly
  • Kremena Lalova
    Kremena Lalova about 10 years
    For some reason in my case $(window).load(function(){ /*code here*/ }) worked
  • colm.anseo
    colm.anseo about 9 years
    one-line: document.onload = function() { ... }
  • jk7
    jk7 about 9 years
    According to w3schools, If async is present: The script is executed asynchronously with the rest of the page (the script will be executed while the page continues the parsing). Perhaps you meant defer instead, like @Daniel Price mentioned?
  • sohaiby
    sohaiby almost 9 years
    window.onload = function worked in my case. I saw people answering $(document).ready(function() for the same question on some other forums, but that doesn't work for me!
  • IAbstract
    IAbstract over 7 years
    For completeness, would you add the jQuery syntax for document load?
  • Suresh Kumar Narayanasamy
    Suresh Kumar Narayanasamy almost 7 years
    So this will add this Function as an ADDITIONAL function to run OnLoad, correct? (rather than replacing an existing onload event)
  • chaos
    chaos almost 7 years
    @ClayNichols: Correct.
  • arodebaugh
    arodebaugh almost 7 years
    @Peter pretty sure this stands alone probably best if it in the bottom of your javascript files so it executes last
  • spottedmahn
    spottedmahn almost 7 years
    document.onload didn't work for me. I found this post w/ the same issue stackoverflow.com/questions/5135638/…. Doesn't seem like document.onload is an option.
  • Zeek2
    Zeek2 over 6 years
    I prefer the first approach, which I find it clearer - esp. when using aspx with only limited on-page javascript.
  • Renan
    Renan over 6 years
  • Mathews Sunny
    Mathews Sunny over 6 years
    Add some description here
  • Chiptus
    Chiptus over 5 years
    This answer depends on jquery
  • The Red Pea
    The Red Pea over 5 years
    document.onload doesnt work in Google Chrome, when used in a separate index.js script file. window.onload does work. (Chrome 71.0.3578.98 (Official Build) (64-bit))
  • tfont
    tfont over 5 years
    This is the most completed answer. onload is after, but people don't realize this at first.
  • ToolmakerSteve
    ToolmakerSteve about 5 years
    Re asynchronous javascript: to clarify, there are two choices for scripts that don't immediately run. Of those, defer is usually preferable to async - because defer won't interrupt html parsing/rendering - and when it runs, DOM is guaranteed to be ready. Efficiently load JavaScript with defer and async.
  • ToolmakerSteve
    ToolmakerSteve about 5 years
    ALL of these options are much later than necessary, given the goal of running javascript once DOM is ready to be manipulated. Two better choices for that goal: 1) Use defer attribute on javascript link in head. 2) move any javascript that accesses DOM to bottom of page, immediately before </body>.
  • wkille
    wkille over 4 years
    +1 I tried window.onload = ... thinking that my script would wait until everything was fully downloaded before running but it seems window.onload actually behaves like document.addEventListener("DOMContentLoaded", ..., whereas the window.addEventListener("load", ... really does wait for everything to be fully downloaded. I would have thought that window.onload should be equivalent to window.addEventListener("load", ... rather than document.addEventListener("DOMContentLoaded", ... ?? I got the same result in Chrome and FF.
  • Metalhead
    Metalhead about 4 years
    Using onload functions are bad style in my eyes, because it just refers to the last assigned function. Look at the answer of DevWL stackoverflow.com/a/36096571/11323907.
  • Ray Foss
    Ray Foss about 4 years
    Reminder: Don't modify objects that aren't yours, specially globals... see Renan's link
  • sarkiroka
    sarkiroka almost 4 years
    I love this solution, because not need any javascript code, but only need is one html attribute <3
  • Akansh
    Akansh over 3 years
    This is wrong fundamentally. Defer does not prevent execution post page onload. Both defer and async scripts are loaded before page load, instead, improves the "domInteraction" time.
  • Daniel Price
    Daniel Price over 3 years
    @Akansh the OP just wanted a way to ensure the DOM had loaded before their script executes. Defer does this, it's literally written in the documentation snippet I shared in my answer.
  • Yunnosch
    Yunnosch almost 3 years
    Please reconsider you rollback which undid a helpful edit. Getting the readability of your posts improved by other users should be considered a good thing.
  • 1.21 gigawatts
    1.21 gigawatts over 2 years
    It looks like you can make inline script load after page load using async false? "To achieve a similar effect for dynamically inserted scripts use async=false instead. - This Boolean attribute is set to indicate to a browser that the script is meant to be executed after the document has been parsed, but before firing DOMContentLoaded."
  • Cardinal System
    Cardinal System over 2 years
    I want my function to be called after a different function which is already listening for the load event. Is there something like a postLoad event?
  • Lucas Vazquez
    Lucas Vazquez over 2 years
    I think this solution, combined with the answer of chaos user (stackoverflow.com/a/807997/10712525), will be the best thing that u can do.
  • RayLoveless
    RayLoveless about 2 years
    @DevWL, I think you meant "defer"... because "async" can still execute before the all the html loads.
  • Ωmega
    Ωmega about 2 years
    Is onload called before or after all resources (such as fonts and images) are loaded and properly visually updated?
  • DevWL
    DevWL almost 2 years
    @RayLoveless yes, I meant defer. So JavaScript pauses render of the DOM there for, the best way would be to place it at the bottom of the page or to load JavaScript script with defer attribute (placed in the header). Thanks