13

I know that IE doesn't have a load event for <script> elements — is there any way to make up for that reliably?

I've seen some talk of things (e.g., requestState == "complete") but nothing very verifiable.


This is to be used so that code can be called after a script is finished loading, so that I don't have to use AJAX to load new sources (thus eliminating issues with cross-domain AJAX).

1
  • Can you just put a function call in the script you're loading that would run as the script is evaluated that would become your completion callback? Commented Jul 17, 2011 at 16:48

3 Answers 3

25

You can use a script loader like head.js. It has its own load callback and it will decrease load time too.


From the headjs code: (slightly modified to be more portable)

function scriptTag(src, callback) { var s = document.createElement('script'); s.type = 'text/' + (src.type || 'javascript'); s.src = src.src || src; s.async = false; s.onreadystatechange = s.onload = function () { var state = s.readyState; if (!callback.done && (!state || /loaded|complete/.test(state))) { callback.done = true; callback(); } }; // use body if available. more safe in IE (document.body || head).appendChild(s); } 
Sign up to request clarification or add additional context in comments.

8 Comments

I'm afraid I don't understand how a library can reduce load time caused by network latency :)
browsers load `<script>' sequentially. head.js loads them asynchronously, but still executes them in the correct order
how do you figure? All the scripts will load faster if you have them loading at the same time as opposed to one after another. Maybe I'm just bad at explaining, there's a good description on the headjs site.
This method allows you to control parallel and serial loading. It also allows you to know when they are completed. This is better than the browser which just loads from the top down synchronously and which will hold up content below.
If code in one script depends on code in another one, that's a sign you might want to be concatenating some of the scripts together if you can.
|
4

I want to add that if you don't support IE7 and below, you don't need onreadystatechange stuff. Source: quircksmode.org

Simplified and working code from original answer:

function loadScript(src, callback) { var s = document.createElement('script'); s.type = 'text/javascript'; s.src = src; s.async = false; if(callback) { s.onload = callback; } document.body.appendChild(s); } 

Comments

2

This is just an extension of ilia's answer. I used scriptTag like this: Works great:

 // these 3 scripts load serially. scriptTag(boot_config.DEPENDENCIES.jquery,function(){ // jquery ready - set a flag scriptTag(boot_config.DEPENDENCIES.jqueryui,function(){ // jqueryui ready - set a flag scriptTag(boot_config.DEPENDENCIES.your_app,function(){ // your_app is ready! - set a flag }); }); }); // these 2 scripts load in paralell to the group above scriptTag(boot_config.EXTERNALS.crypto,function(){ // crypto ready - set a flag }); scriptTag(boot_config.EXTERNALS.cropper,function(){ // cropper ready - set a flag }); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.