$(window).load fires too quickly in IE with asynchronous js libs

1k Views Asked by At

I have some serious problem with getting asynchronously some js libs and executing them in $(window).load in IE

all works in other browsers of course

so the problem is, that I'm doing something like

 <script type="text/javascript">
 var scr1 = document.createElement('script'); 
 scr1.type = 'text/javascript'; 
 scr1.src = 'some_lib.js'; 
 $('BODY').prepend(scr1); 
</script>

Just before </body> and use $(window).load method in html above it to operate on some plugins in some_lib.js, but it all happens to fast in IE, probable because of that asynchronous lib including, and I get an error, that method is not available for the element.

Is there any chance of maybe modyfying $(window).load method so I still could use it in the same way for every browser ?

2

There are 2 best solutions below

2
On

Any code that you have in the window.load() call must be placed in a function (called onLoad in this example).

Every time you have a script that you dynamically load, increment a counter. Also include something to decrement that counter...

src1.onload = function() { counter--; onLoad(); }

Then in 'onLoad' have the first line...

if (counter > 0) return;

That means that onLoad will fire at window.load and after every script is loaded, but will only execute when it's all loaded.

It's scrappy, but it will solve your problem.

3
On

You haven't really described the reason you need to load these libraries asynchronously. Third party libraries often have "on script load" functionality that you can define before the script is loaded. If you need to load multiple libraries before you can execute your code, you may have to either 1. fire up some code every time a library is loaded to test to see if all libraries required are loaded and then fire off you code 2. for every library, create a jQuery promise/deferred to get resolved when that library is loaded and use $.when(promises).done(function/code) to test and run the code whenever a particular set is loaded, or 3. rewrite to use RequireJS. If these libraries are YOUR code, well, you may have to add start up code to your libraries anyway; It might be a good time to learn RequireJS.

I wish I could recommend further, but learning the basics behind RequireJS has always been on my todo list, but it hasn't been done; I just know of people here successfully using it. If that seems like too much trouble, I'd consider some variant of option 2. If you don't know what jQuery would be used eh... you may be stuck with option 1 or 3.

Edit:

Of course, that's not to say that jQuery has got the only promise library, I just often recommend using promises in some form for these kind of things..

Archer's technique looks interesting, I just don't know how reliable it is (it might be quite reliable, I just would like to see proof/documentation). You could combine that with option 2 also, quite well, if you want to short-cut execution for some things while leaving others to be dealt asynchronously and if those script onload methods really work as expected.