document.createElement('script')... adding two scripts with one callback
I need to add prototype and then add scriptaculous and get a callback when they are both done loading. I am currently loading prototype like so:
var script = document.createElement("script");
script.src = "http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js";
script.onload = script.onreadystatechange = callback;
document.body.appendChild( script );
I could do this by chaining the callbacks, but that seems like poor practice ( I don't want a silly chain of 20 callback methods when I need to load more scripts). Ideas?
Solution 1:
I propose you to use some small loader which will chain and do stuff for you. For example like this one:
function loadScripts(array,callback){
var loader = function(src,handler){
var script = document.createElement("script");
script.src = src;
script.onload = script.onreadystatechange = function(){
script.onreadystatechange = script.onload = null;
handler();
}
var head = document.getElementsByTagName("head")[0];
(head || document.body).appendChild( script );
};
(function run(){
if(array.length!=0){
loader(array.shift(), run);
}else{
callback && callback();
}
})();
}
This script should help you to build the script tags and call your callback when all files are loaded. Invoke is pretty easy:
loadScripts([
"http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js",
"http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js"
],function(){
alert('All things are loaded');
});
Hope this will help
Solution 2:
Because of a bug in Internet Explorer the recursive loader program from nemisj is not working correct in IE. Can be solved by setting a delay on the recursive call like:
function loadScripts(array,callback){
var loader = function(src,handler){
var script = document.createElement("script");
script.src = src;
script.onload = script.onreadystatechange = function(){
script.onreadystatechange = script.onload = null;
if(/MSIE ([6-9]+\.\d+);/.test(navigator.userAgent))window.setTimeout(function(){handler();},8,this);
else handler();
}
var head = document.getElementsByTagName("head")[0];
(head || document.body).appendChild( script );
};
(function(){
if(array.length!=0){
loader(array.shift(),arguments.callee);
}else{
callback && callback();
}
})();
}
This small hack does it, and often is the solution in IE, when an unexplainable problem occurs, which is too often.