For my website I wanted to use conditional javascript loading when certain elements are detected. At first I only created a new script element and append it to the head. When I do this the commands following that statement would always fail because the browser is still loading the javascript file and the function is not ready yet. $("element").something is not a function
A second problem was when another part of my script wanted to include a script that was already requested before. I could not safely assume the script would always still be loading or was already loaded upon that point.
So I wrote a script that could execute callbacks when a script/scripts is/are loaded. This is how my function looks like now:
/* LOADING LIST */
var loading = new Array();
function include(script, callback) {
if (script instanceof Array) {
/* load an array of scripts */
if (script.length > 1) {
var top = script.shift();
include(top, function() {
include(script, callback);
});
} else
include(script[0], callback);
} else {
var source = base_url + script;
var type = /[^.]+$/.exec(script);
if (type == "js") {
if ($('script[src="' + source + '"]').length == 0) {
/* first time script is requested */
loading[script] = true;
var e = document.createElement('script');
e.src = source;
e.type = "text/javascript";
e.onload = function() {
delete loading[script];
if (callback !== undefined) {
callback();
}
};
document.getElementsByTagName("head")[0].appendChild(e);
}
else if(script in loading) {
/* script is being loaded */
var e = $('script[src="' + source + '"]')[0];
var old = e.onload;
e.onload = function() {
old();
callback();
};
}
else {
/* script is loaded */
callback();
}
}
else if (type == "css") {
/* no need to wait for stylesheets */
if ($('link[href="' + source + '"]').length == 0) {
var e = document.createElement('link');
e.rel = 'stylesheet';
e.type = 'text/css';
e.href = source;
document.getElementsByTagName("head")[0].appendChild(e);
}
if (callback !== undefined) {
callback();
}
}
}
}
It supports things like this:
if($('.wysiwyg').length>0) {
include(['javascript/ckeditor/ckeditor.js','javascript/ckeditor/adapters/jquery.js'], function() {
$(".wysiwyg").ckeditor();
}
}
This will only execute the callback when all the mentioned scripts are loaded.
I do not know very much about javascript and I was wondering if this script could become shorter and/or more efficient.