Benito Ciaro
Benito Ciaro

Reputation: 1748

Browser event when all JS files loaded

My AJAX app is basically one index.html plus a bunch of .js modules. My setup function hooks up the js handler code to the appropriate DOM element. I suspect I need to use window.onload() rather than jquery's $(document).ready() since all the .js files need to be available (i.e. downloaded) at hookup time.

My understanding is that only the DOM tree is ready at $(document).ready(), but there's no guarantee that the .js files have been loaded. Is that correct?

PS. I don't need multiple onload handlers; a single window.onload() is fine for me.

Upvotes: 1

Views: 7676

Answers (4)

Jared Farrish
Jared Farrish

Reputation: 49238

I setup two files as a test:

syncscript.html

<html>
<head>
<title></title>
<style type="text/css">
</style>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
$(window).load(function(){
    $(document.body).append('<p>window.load has run.');
});
$(document).ready(function(){
    $(document.body).append('<p>document.ready has run.');
});
</script>
</head>
<body>
<p>Page has loaded. Now continuing page load and attempting to load additional script file (after 10 second pause).</p>
<script type="text/javascript">
var p = document.createElement('p');
p.innerHTML = '<p>Inline script preceding jssleep.php file has run.</p>';
document.body.appendChild(p);
</script>
<script type="text/javascript" src="http://jfcoder.com/test/jssleep.php"></script>
<script type="text/javascript">
var p = document.createElement('p');
p.innerHTML = '<p>This is an inline script that runs after the jssleep.php script file has loaded/run.</p>';
document.body.appendChild(p);
</script>
</body>
</html>

jssleep.php

<?php

header("content-type: text/javascript");

sleep(10);

?>
var p = document.createElement('p');
p.innerHTML = '<p>jssleep.php script file has loaded and run following &lt;?php sleep(10); ?>.</p>';
document.body.appendChild(p);

This outputs (in Firefox):

Page has begun loading. Now continuing page load and attempting to load additional script file (after 10 second pause).

Inline script preceding jssleep.php file has run.

jssleep.php script file has loaded and run following <?php sleep(10); ?>.

This is an inline script that runs after the jssleep.php script file has loaded/run.

$(document).ready() has run.

$(window).load() has run.

Upvotes: 1

Mad Man Moon
Mad Man Moon

Reputation: 739

You definitely have a misunderstanding in this case. The whole reason why it is considered best practice to include your script tags just before the close of the body tag is because script loads are blocking loads. Unless specifically coded otherwise (i.e.; google analytics), JavaScript files are loaded synchronously.

That said, if there are dependencies between script files, the order in which the files are loaded can be important.

Upvotes: 3

rgthree
rgthree

Reputation: 7273

No, you can safely use $(document).ready() as long as your script tags are loaded synchronously (in most cases, this means "normally"). The browser waits for a <script> to be loaded before continuing. Therefore, $(document).ready() includes all <script> tags in the source.

There are two exceptions to this, if the script tags contains an async or defer attribute. The prior meaning the compatible browsers can continue rendering the page, and the latter signifying that the script is executed when the page has finished.

Upvotes: 1

Niet the Dark Absol
Niet the Dark Absol

Reputation: 324820

That is correct. However window.onload also requires CSS and images to be downloaded, so may be a bit overkill.

What you can do is this:

var scriptsToLoad = 0;
// for each script:
s = document.createElement('script');
s.type = "text/javascript";
s.src = "path/to/file.js";
scriptsToLoad += 1;
s.onload = function() {scriptsToLoad -= 1;};
// after all scripts are added in the code:
var timer = setInterval(function() {
    if( scriptsToLoad == 0) {
        clearInterval(timer);
        // do stuff here
    }
},25);

Upvotes: 0

Related Questions