Javascript include function with callback when loaded
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开发者_如何学JAVA shorter and/or more efficient.
you should use $.getScript() from jQuery. It does what you are doing. And you can also make it load synchronous with $.ajaxSetup({async: false});
for example
$.ajaxSetup({async: false});
$.getScript('myClass.js');
imFromMyClass();
I use a function like:
function require(module) {
$.ajaxSetup({async: false, cache: true});
if (window['matchExtension'] === undefined) {
window['matchExtension'] = function(filename, extensions) {
return (getFileExtension(filename).match(new RegExp("(" + extensions + ")", "ig")));
}
}
if (typeof module == 'string') {
var tmp = "";
if (matchExtension(module, "htm*") || matchExtension(module, "txt")) {
tmp = $.get(module).responseText;
return tmp;
} else if (matchExtension(module, "css")) {
var obj = $.get(module);
if (obj.status == 404) return '';
tmp = obj.responseText;
var el = document.createElement('style');
el.type = 'text/css';
el.media = 'screen';
document.getElementsByTagName('head')[0].appendChild(el);
if(el.styleSheet) el.styleSheet.cssText = tmp;// IE method
else el.appendChild(document.createTextNode(tmp));// others
} else if (module.EndsWith("/")) {
return $.get(module).responseText; // directory listing
} else {
$.getScript(module);
}
} else {
$.ajaxSetup({async: false, cache:true});
for (var i =0, len = module.length; i < len; i++) $.getScript(module[i]);
}
return true;
}
var content = require('someFile.html');
require('someStyle.css');
require('someClass.js');
require(['class1.js', 'class2.js', 'class3.js']);
one other improvement you can do when loading an array of javascript files is to serve the list to a server script that concatenates them all in the same response
精彩评论