I'm trying to do something AFTER a script is completely loaded. (IE8)
Script I use for testing: http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js
and the invalid one: http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.minaaaaaaaa.js
The code...
var script = create the element and append to head...
// this works fine with FF/Chrome/...
script.onload = function() {alert('script loading complete');}
script.onerror = function() {alert('error loading script');}
// and for IE
script.onreadystatechange = function() {
// this will alert 1.loading 2.loaded
alert(this.readyState);
// this never works
if(this.readyState == 'complete') {alert('script loading complete');}
// this works with either a valid or INVALID url
else if(this.readyState == 'loaded') {alert('script loaded');}
};
In my case, the "complete" never shows, the "loaded" shows even if a url is invalid. So there's no way to tell if a script is CORRECTLY loaded UNDER IE.
Am I doing something wrong? How come I never get the complete state?
OK, I just read some articles and it seems that readystate is not a reliable way to detect script loading.
So is there another way to do so? without jQuery, but pure Javascript.
I've found out a trick how to make script node become 'complete' in IE7 and IE8. And also how to detect when error really happens when loading script (node.onerror working only in IE9+). The hack is in
Try it!
var node = document.createElement('script');
node.src = 'some-[un]existing-url.js';
node.type = 'text/javscript';
node.onreadystatechange = (function(node) {
return function () {
if (/loaded|complete/.test(node.readyState)) {
_finish();
}
};
})(node);
var _finish=function() {
if (node.readyState == 'complete') {
// insert node only after completing the request, though this is not necessary
var head = document.head;
head || (head = document.getElementsByTagName('head')[0]);
head.appendChild(node);
// call success function
_success();
return;
}
var firstState = node.readyState;
// hack: calling 'children' property changes node's readyState from 'loaded' to complete
// (if script was loaded normally) or to 'loading' - if error detected
node.children;
// error detected
if (firstState == 'loaded' && node.readyState == 'loading') {
// custom error code
_error();
}
}
As per your comment, here's a schematic of how to dynamically add a script tag using XHR (XMLHttpRequest
):
var handleRequest = function( ) { //!! set up the handleRequest callback
if(this.status != undefined) {
/* do something with the status code here */
}
if(this.readyState == 4) {
var script = document.createElement("script") ;
script.setAttribute("type","text/javascript") ;
var text = document.createTextNode(this.responseText) ;
script.appendChild(text) ;
var head = document.getElementsByTagName("head")[0] ;
head.insertBefore(script,head.firstChild) ;
}
} ;
var request ; //!! supposing you have a way to get a working XHR Object
//.. set the XHR Object
request.open("GET",url,true) ;
request.overrideMimeType("text/javascript") ;
request.onreadystatechange = handleRequest ;
request.send(null) ;
Please keep in mind that this is only to give you an idea of what I mean. A working example would have to be way more elaborate judging from the jQuery source code.
Links:
W3 documentation for XMLHttpRequest
MDN documentation for XMLHttpRequest
MSDN documentation for XMLHttpRequest
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With