77

We have several JavaScript files which we load at the bottom of the master page. However, I have the situation that I need to perform some JavaScript before the other scripts are loaded. Is it possible to wait till all the JavaScript files are loaded and then execute some JavaScript code?

I thought $(document).ready() did this, but as it turns out, it doesn't. Of course we can move the script files from the bottom to the top, but I am wondering if it's possible what I want.

Hydrid
  • 87
  • 1
  • 10
Martijn
  • 24,441
  • 60
  • 174
  • 261
  • You can use a `script` loader to do it after you do your own script. – Jared Farrish Jun 29 '12 at 07:57
  • 3
    I don't think it's clear what you want - you talk, at the same time, of both wanting to perform X *before* other scripts are loaded, but also wanting to wait until all scripts *are* loaded. Which is it? And what is the nature of the X that you wish to perform? – Damien_The_Unbeliever Jun 29 '12 at 07:59
  • @Damien_The_Unbeliever TGo be more clear: I want to execute javascript after all javascript files are loaded. – Martijn Jun 29 '12 at 08:31

5 Answers5

126

You can use

$(window).on('load', function() {
    // your code here
});

Which will wait until the page is loaded. $(document).ready() waits until the DOM is loaded.

In plain JS:

window.addEventListener('load', function() {
    // your code here
})
Simone
  • 20,302
  • 14
  • 79
  • 103
Eruant
  • 1,816
  • 2
  • 14
  • 22
  • 3
    Here is a better explanation http://4loc.wordpress.com/2009/04/28/documentready-vs-windowload/ – Eruant Jun 29 '12 at 08:01
  • Worked well for my application which needed to wait until dynamically loaded scripts were finished loading before generating page content. +1 – Yogi Oct 11 '17 at 16:49
  • 8
    The plain old JavaScript equivalent is: `window.addEventListener('load', function() { /* your code here */ })`. – Dave Land Aug 24 '18 at 21:31
  • does this appends the execution stack or replaces the old one? – Amit Shah Mar 05 '19 at 11:08
37

You can use .getScript() and run your code after it loads:

 $.getScript("my_lovely_script.js", function(){

    alert("Script loaded and executed.");
    // here you can use anything you defined in the loaded script

 });

You can see a better explanation here: How do I include a JavaScript file in another JavaScript file?

Community
  • 1
  • 1
Control Freak
  • 12,965
  • 30
  • 94
  • 145
34

You can use <script>'s defer attribute. It specifies that the script will be executed when the page has finished parsing.

<script defer src="path/to/yourscript.js">

A nice article about this: http://davidwalsh.name/script-defer

Browser support seems pretty good: http://caniuse.com/#search=defer

Another great article about loading JS using defer and async: https://flaviocopes.com/javascript-async-defer/

Simone
  • 20,302
  • 14
  • 79
  • 103
  • 3
    It does not seem to wait for all other JS files to have executes, at least not in Firefox. – Rolf Sep 12 '17 at 21:13
  • 7
    Like the doc says, defer script loads when the page is parsed (instead of when js/css is loaded). This ain't a solution. – Nishant Oct 16 '18 at 05:03
5

Expanding a bit on @Eruant's answer,

$(window).on('load', function() {
    // your code here
});

Works very well with both async and defer while loading on scripts.

So you can import all scripts like this:

<script src="/js/script1.js" async defer></script>
<script src="/js/script2.js" async defer></script>
<script src="/js/script3.js" async defer></script>

Just make sure script1 doesn't call functions from script3 before $(window).on('load' ..., make sure to call them inside window load event.

More about async/defer here.

Alpha2k
  • 2,212
  • 7
  • 38
  • 65
0

Thats work for me:

var jsScripts = [];

jsScripts.push("/js/script1.js" );
jsScripts.push("/js/script2.js" );
jsScripts.push("/js/script3.js" );

$(jsScripts).each(function( index, value ) {
    $.holdReady( true );
    $.getScript( value ).done(function(script, status) {
        console.log('Loaded ' + index + ' : ' + value + ' (' + status + ')');                
        $.holdReady( false );
    });
});