854

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?

Kamil Kiełczewski
  • 53,729
  • 20
  • 259
  • 241
Robin Rodricks
  • 99,791
  • 133
  • 372
  • 575

26 Answers26

962

These solutions will work:

<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.

Community
  • 1
  • 1
marcgg
  • 60,067
  • 49
  • 172
  • 221
  • 6
    What is the difference between and document.onload=function ... ? – Mentoliptus Aug 16 '11 at 10:14
  • 15
    @mentoliptus: `document.onload=` is non obtrusive http://en.wikipedia.org/wiki/Unobtrusive_JavaScript – marcgg Sep 05 '11 at 10:05
  • 3
    script in the html ...no no no $(function() { code here }); –  Jan 17 '14 at 13:12
  • 25
    @gerdi OP didn't mention anything about jQuery. I also gave an unobtrusive option in my answer. – marcgg Jan 29 '14 at 14:48
  • @gerdi No problem, I edited my answer to show the difference more clearly – marcgg Jan 29 '14 at 14:53
  • For some reason in my case $(window).load(function(){ /*code here*/ }) worked – Kremena Lalova Apr 16 '14 at 13:12
  • `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! – sohaiby Jul 02 '15 at 07:45
  • For completeness, would you add the `jQuery` syntax for document load? – IAbstract Oct 10 '16 at 03:25
  • 5
    document.onload didn't work for me. I found this post w/ the same issue https://stackoverflow.com/questions/5135638/why-does-window-onload-work-while-document-onload-doesnt. Doesn't seem like document.onload is an option. – spottedmahn Jul 28 '17 at 19:44
  • I prefer the first approach, which I find it clearer - esp. when using aspx with only limited on-page javascript. – Zeek2 Oct 17 '17 at 07:46
  • `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)) – The Red Pea Jan 21 '19 at 05:59
  • 3
    *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 `

    `.

    – ToolmakerSteve Apr 30 '19 at 21:10
  • Using onload functions are bad style in my eyes, because it just refers to the last assigned function. Look at the answer of DevWL https://stackoverflow.com/a/36096571/11323907. – MrXeth Feb 09 '20 at 18:07
296

Keep in mind that loading the page has more than one stage. Btw, this is pure JavaScript

"DOMContentLoaded"

This event is fired when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, 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 img 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 stylesheets

"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.

Exectues after everything is loaded and parsed:

window.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

Antonio Laguna
  • 8,137
  • 7
  • 31
  • 68
DevWL
  • 11,946
  • 5
  • 71
  • 69
  • 1
    @Peter pretty sure this stands alone probably best if it in the bottom of your javascript files so it executes last – arodebaugh Jul 18 '17 at 14:59
  • 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 async in the header. – DevWL Sep 25 '17 at 22:29
  • 2
    This is the most completed answer. onload is after, but people don't realize this at first. – tfont Jan 24 '19 at 10:26
  • 1
    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](https://flaviocopes.com/javascript-async-defer/#blocking-rendering). – ToolmakerSteve Apr 30 '19 at 20:18
  • 1
    +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. – wkille Jan 24 '20 at 11:58
206

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;
    }
}
chaos
  • 115,791
  • 31
  • 292
  • 308
  • 12
    +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. – Grant Wagner Apr 30 '09 at 21:07
  • 6
    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. – Grant Wagner May 04 '09 at 20:00
  • So this will add this Function as an ADDITIONAL function to run OnLoad, correct? (rather than replacing an existing onload event) – Clay Nichols Jun 09 '17 at 04:47
  • @ClayNichols: Correct. – chaos Jun 09 '17 at 22:15
  • 2
    Good solution, but now outdated: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/attachEvent – Renan Nov 26 '17 at 05:25
  • Reminder: Don't modify objects that aren't yours, specially globals... see Renan's link – Ray Foss Apr 10 '20 at 00:47
133

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.

Nordes
  • 2,396
  • 2
  • 18
  • 30
73

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.

Daniel Price
  • 1,062
  • 7
  • 17
  • I love this solution, because not need any javascript code, but only need is one html attribute <3 – sarkiroka May 10 '20 at 19:07
  • 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. – Akansh Oct 20 '20 at 07:13
  • @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. – Daniel Price Jan 31 '21 at 22:42
31

Here's a script based on deferred js loading after the page is loaded,

<script type="text/javascript">
  function downloadJSAtOnload() {
      var element = document.createElement("script");
      element.src = "deferredfunctions.js";
      document.body.appendChild(element);
  }

  if (window.addEventListener)
      window.addEventListener("load", downloadJSAtOnload, false);
  else if (window.attachEvent)
      window.attachEvent("onload", downloadJSAtOnload);
  else window.onload = downloadJSAtOnload;
</script>

Where do I place this?

Paste code in your HTML just before the </body> tag (near the bottom of your HTML file).

What does it do?

This code says wait for the entire document to load, then load the external file deferredfunctions.js.

Here's an example of the above code - Defer Rendering of JS

I wrote this based on defered loading of javascript pagespeed google concept and also sourced from this article Defer loading javascript

Lucky
  • 14,677
  • 16
  • 104
  • 145
22

Look at hooking document.onload or in jQuery $(document).load(...).

Daniel A. White
  • 174,715
  • 42
  • 343
  • 413
14

JavaScript

document.addEventListener('readystatechange', event => { 

    // When HTML/DOM elements are ready:
    if (event.target.readyState === "interactive") {   //does same as:  ..addEventListener("DOMContentLoaded"..
        alert("hi 1");
    }

    // When window loaded ( external resources are loaded too- `css`,`src`, etc...) 
    if (event.target.readyState === "complete") {
        alert("hi 2");
    }
});

same for jQuery:

$(document).ready(function() {   //same as: $(function() { 
     alert("hi 1");
});

$(window).load(function() {
     alert("hi 2");
});





NOTE: - Don't use the below markup ( because it overwrites other same-kind declarations ) :

document.onreadystatechange = ...
T.Todua
  • 44,747
  • 17
  • 195
  • 185
12

Working Fiddle on <body onload="myFunction()">

<!DOCTYPE html>
<html>
 <head>
  <script type="text/javascript">
   function myFunction(){
    alert("Page is loaded");
   }
  </script>
 </head>

 <body onload="myFunction()">
  <h1>Hello World!</h1>
 </body>    
</html>
Aamir Shahzad
  • 5,940
  • 8
  • 43
  • 62
10
<script type="text/javascript">
  function downloadJSAtOnload() {
   var element = document.createElement("script");
   element.src = "defer.js";
   document.body.appendChild(element);
  }
  if (window.addEventListener)
   window.addEventListener("load", downloadJSAtOnload, false);
  else if (window.attachEvent)
   window.attachEvent("onload", downloadJSAtOnload);
  else window.onload = downloadJSAtOnload;
</script>

http://www.feedthebot.com/pagespeed/defer-loading-javascript.html

TylerH
  • 19,065
  • 49
  • 65
  • 86
Frankey
  • 3,551
  • 24
  • 25
9

If you are using jQuery,

$(function() {...});

is equivalent to

$(document).ready(function () { })

or another short hand:

$().ready(function () { })

See What event does JQuery $function() fire on? and https://api.jquery.com/ready/

rogerdpack
  • 50,731
  • 31
  • 212
  • 332
Benjamin Crouzier
  • 34,915
  • 36
  • 154
  • 219
8

I find sometimes on more complex pages that not all the elements have loaded by the time window.onload is fired. If that's the case, add setTimeout before your function to delay is a moment. It's not elegant but it's a simple hack that renders well.

window.onload = function(){ doSomethingCool(); };

becomes...

window.onload = function(){ setTimeout( function(){ doSomethingCool(); }, 1000); };
ekostadinov
  • 6,642
  • 3
  • 24
  • 46
Charles Jaimet
  • 659
  • 6
  • 9
7
document.onreadystatechange = function(){
     if(document.readyState === 'complete'){
         /*code here*/
     }
}

look here: http://msdn.microsoft.com/en-us/library/ie/ms536957(v=vs.85).aspx

Arthur Tsidkilov
  • 5,143
  • 2
  • 18
  • 16
5

Just define <body onload="aFunction()"> that will be called after the page has been loaded. Your code in the script is than enclosed by aFunction() { }.

fragilewindows
  • 1,324
  • 1
  • 13
  • 25
Norbert Hartl
  • 9,675
  • 5
  • 33
  • 45
4
<body onload="myFunction()">

This code works well.

But window.onload method has various dependencies. So it may not work all the time.

Hakan KOSE
  • 731
  • 9
  • 15
Akarsh Satija
  • 1,600
  • 20
  • 28
3

There is a very good documentation on How to detect if document has loaded using Javascript or Jquery.

Using the native Javascript this can be achieved

if (document.readyState === "complete") {
 init();
 }

This can also be done inside the interval

var interval = setInterval(function() {
    if(document.readyState === 'complete') {
        clearInterval(interval);
        init();
    }    
}, 100);

Eg By Mozilla

switch (document.readyState) {
  case "loading":
    // The document is still loading.
    break;
  case "interactive":
    // The document has finished loading. We can now access the DOM elements.
    var span = document.createElement("span");
    span.textContent = "A <span> element.";
    document.body.appendChild(span);
    break;
  case "complete":
    // The page is fully loaded.
    console.log("Page is loaded completely");
    break;
}

Using Jquery To check only if DOM is ready

// A $( document ).ready() block.
$( document ).ready(function() {
    console.log( "ready!" );
});

To check if all resources are loaded use window.load

 $( window ).load(function() {
        console.log( "window loaded" );
    });
3

Use this code with jQuery library, this would work perfectly fine.

$(window).bind("load", function() { 

  // your javascript event

});
Harish Kumar
  • 74
  • 1
  • 10
3
$(window).on("load", function(){ ... });

.ready() works best for me.

$(document).ready(function(){ ... });

.load() will work, but it won't wait till the page is loaded.

jQuery(window).load(function () { ... });

Doesn't work for me, breaks the next-to inline script. I am also using jQuery 3.2.1 along with some other jQuery forks.

To hide my websites loading overlay, I use the following:

<script>
$(window).on("load", function(){
$('.loading-page').delay(3000).fadeOut(250);
});
</script>
TylerH
  • 19,065
  • 49
  • 65
  • 86
3

Using the YUI library (I love it):

YAHOO.util.Event.onDOMReady(function(){
    //your code
});

Portable and beautiful! However, if you don't use YUI for other stuff (see its doc) I would say that it's not worth to use it.

N.B. : to use this code you need to import 2 scripts

<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/yahoo/yahoo-min.js" ></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/event/event-min.js" ></script>
Valentin Jacquemin
  • 2,119
  • 1
  • 18
  • 33
2

Comparison

In below snippet I collect choosen methods and show their sequence. Remarks

  • the document.onload (X) is not supported by any modern browser (event is never fired)
  • if you use <body onload="bodyOnLoad()"> (F) and at the same time window.onload (E) then only first one will be executed (because it override second one)
  • event handler given in <body onload="..."> (F) is wrapped by additional onload function
  • document.onreadystatechange (D) not override document .addEventListener('readystatechange'...) (C) probably cecasue onXYZevent-like methods are independent than addEventListener queues (which allows add multiple listeners). Probably nothing happens between execution this two handlers.
  • all scripts write their timestamp in console - but scripts which also have access to div write their timestamps also in body (click "Full Page" link after script execution to see it).
  • solutions readystatechange (C,D) are executed multiple times by browser but for different document states:
    • loading - the document is loading (no fired in snippet)
    • interactive - the document is parsed, fired before DOMContentLoaded
    • complete - the document and resources are loaded, fired before body/window onload

<html>

<head>
  <script>
    // solution A
    console.log(`[timestamp: ${Date.now()}] A: Head script`);
    
    // solution B
    document.addEventListener("DOMContentLoaded", () => {
      print(`[timestamp: ${Date.now()}] B: DOMContentLoaded`);
    });

    // solution C
    document.addEventListener('readystatechange', () => {
      print(`[timestamp: ${Date.now()}] C: ReadyState: ${document.readyState}`);
    });
   
    // solution D
    document.onreadystatechange = s=> {print(`[timestamp: ${Date.now()}] D: document.onreadystatechange ReadyState: ${document.readyState}`)};
    
    // solution E (never executed)
    window.onload = () => {
      print(`E: <body onload="..."> override this handler`);
    };

    // solution F
    function bodyOnLoad() {
      print(`[timestamp: ${Date.now()}] F: <body onload='...'>`);      
      infoAboutOnLoad(); // additional info
    }
    
    // solution X
    document.onload = () => {print(`document.onload is never fired`)};



    // HELPERS

    function print(txt) { 
      console.log(txt);
      if(mydiv) mydiv.innerHTML += txt.replace('<','&lt;').replace('>','&gt;') + '<br>';
    }
    
    function infoAboutOnLoad() {
      console.log("window.onload (after  override):", (''+document.body.onload).replace(/\s+/g,' '));
      console.log(`body.onload==window.onload --> ${document.body.onload==window.onload}`);
    }
            
    console.log("window.onload (before override):", (''+document.body.onload).replace(/\s+/g,' '));

  </script>
</head>

<body onload="bodyOnLoad()">
  <div id="mydiv"></div>

  <!-- this script must te at the bottom of <body> -->
  <script>
    // solution G
    print(`[timestamp: ${Date.now()}] G: <body> bottom script`);
  </script>
</body>

</html>
Kamil Kiełczewski
  • 53,729
  • 20
  • 259
  • 241
1

As Daniel says, you could use document.onload.

The various javascript frameworks hwoever (jQuery, Mootools, etc.) use a custom event 'domready', which I guess must be more effective. If you're developing with javascript, I'd highly recommend exploiting a framework, they massively increase your productivity.

Iain
  • 615
  • 1
  • 6
  • 10
0

My advise use asnyc attribute for script tag thats help you to load the external scripts after page load

<script type="text/javascript" src="a.js" async></script>
<script type="text/javascript" src="b.js" async></script>
Kalidass
  • 382
  • 2
  • 17
  • 9
    According to [w3schools](http://www.w3schools.com/tags/att_script_async.asp), _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? – jk7 Apr 15 '15 at 00:06
0

<script type="text/javascript">
$(window).bind("load", function() { 

// your javascript event here

});
</script>
Jared Lovin
  • 543
  • 9
  • 23
Vô Vị
  • 173
  • 1
  • 2
0

You can write a fonction on a specific script file and call it in to your body element, by using onload attribute.

Exemple:

<script>
  afterPageLoad() {
   //your code here
}
</script>

Now call your script into your html page by using script tag:

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

into your body element; add onload attribute like this:

<body onload="afterPageLoad();">
-1

In simple terms just use "defer" in the script tag.

.....
-1

i can catch page load by this code

<script>
console.log("logger saber");

window.onload = (event) => {
  console.log('page is fully loaded');
document.getElementById("tafahomNameId_78ec7c44-beab-40de-9326-095f474519f4_$LookupField").value = 1;;
};

</script>
saber tabatabaee yazdi
  • 2,078
  • 3
  • 26
  • 40