I'm rebuilding my lazy loader module to accept asyncronus request but i have a BIG problem:
internet explorer don't support script.onload/onerror!!!
The old script did globally eval the target script source read with an ajax sync call, it works very well,it's cross browser and i can make it async editing 1 variable but it's very tricky to debug(ALL the source code is executed in one single line and the browser gives not to much infos about the errors,dividing the code by line with a regexp is IMPOSSIBLE because js have blocks with infinite depth and regexp are simply not good at this).
This is the code that i use to create the script(a classic):
var script = document.createElement('script');
script.type = 'text/javascript';
script.src =name;
script.name =name;
script.async = true;
script.onload=<my_onload_code>;
script.onerror=<my_onerror_code>;
it won't work on IE because it doesen't support onload and onerror with the script;
the code below is a fix but works only if the script isn't async
if(script.onreadystatechange!==undefined)//only IE T_T
script.onreadystatechange = function() {
if (script.readyState == 'loaded')//ERROR LOADING
<my_onerror_code>;
else
if(script.readyState == 'complete')//loaded
<my_onload_code>;
};
i can test it every X milliseconds until the script is loaded but it's an ugly solution and i want to avoid it.
EDIT: this is the code i tryed to check every X ms if the script is loaded, it's not that bad and it works better than ajax;the problem is that i can't know if the script is loaded with success or with error(onload or onerror).
var script = document.createElement('script');
script.type = 'text/javascript';
script.src =name;
script.name =name;
script.async = true;
script.onload=function(){Lazy_loader.onload(this);};
script.onerror=function(){Lazy_loader.onerror(this);};
if(script.onreadystatechange!==undefined){//ie fix T_T
script.timer=setInterval(function(){
if (script.readyState == 'loaded' || script.readyState == 'complete')}//ERROR LOADING
if(LOADED???)//loaded
Lazy_loader.onload(script);
else
Lazy_loader.onerror(script);
clearInterval(script.timer);
}
},100);
}
document.getElementsByTagName('head')[0].appendChild(script);
i tryed to use addEventListener/attachEvent functions but it didn't seem to work(even using addEvent functions from the web)
summarizing the options seems to be:
- Use AJAX and global eval to load the script(debugging hell)
- Use AJAX and global eval only with IE(may be a solution,i don't use IE)
- Use AJAX and global eval only if the script contains errors(i need to check timings problems because with my code i "simulate" syncronous code even if the call is async)
- Test script.onreadystatechange (only on IE) every X time until it's loaded(UGLY!!!)
- Use window.onload : AVOID,it need to charge ALL the page,i need to call it when ONLY one script is launched(see details on endpage)
- Add a code on the source of each script (AVOID like said on endpage)
- fix the script.onload for IE(using addEventListener/attachEvent?!?)
PLEASE PAY ATTENTION:
i don't want to use window.onload because it's fired only when ALL the page is loaded,i need to fire it when only the target script is loaded(my lazy loading script is a lot more complex so please don't ask why);
i DO NOT WANT to use ANY third party library(like jquery,prototype,etc.),
i don't even want to edit the target script source(like when using JSPON or adding a script to alert that the script is loaded).
Hope that's not too much! Thanks.
This is one solution: if it's IE i'll simply load the text with an async ajax call and then set the script.text to the loaded data. IE seems to lock onload and onerror(for security reasons?)and not script.text(some other browsers may not allow it for security resons to prevent XSS attacks like on iframes),i don't know why microsoft can't simply respect standards,i simply hate ie and "tricks" to fix theyr's desing problems.
this works well on most browsers(IE/chrome/firfox tested for now)and i tested loading 3 files:
and they're loaded in a total of 40XX ms in all browsers(some extra time is taken by the browser to call the onload/onerror script),i can also(with my lazy loader script)simulate a sync loading executing code only after all files in queue are loaded.
If you know a better way or if you know errors that may occur in this implementation please reply! Thanks!
Try this one: https://stackoverflow.com/a/18840568/2785975. Here the problem for IE7-8 with onerror event is described and decision is shown.
I have to say that regardless whether
async
is set or not, usingreadyState = 'loaded'
to check error is not enough. In fact,loaded
will be triggered in situations loading error script or the first time to load correct script.You can append
src
with random query string to disable the cache, then check thereadyState
.ignore the junk below. the nextSibling thing was a result of being in the debugger and wasn't really reproducible in the real world. instead, i would have to recommend checking out www.requirejs.org
it provides a method that is about as close to an include or import statement as you could find in js.
this is a totally goofball solution, and i will be following this thread for comments about why this works, but here goes how i fixed this without a timer.
like i said i don't know WHY nextSibling is null on a 404'd attempt, but if the js url was correct, nextSibling had a value.