日期:2014-05-16  浏览次数:20396 次

动态加载JS文件

/**
?* 动态加载JS文件,
?* @return {}
?*/
var JsLoader = function(config) {

?return {
??/**
?? * 动态加载.js文件。当全部文件加载完后,执行回调函数。
?? * 如果文件加载顺序很重要,则需要设置preserveOrder参数为true
?? * @param {Array} 文件名称列表
?? * @param {Function} 全部文件加载完后,需要执行的回调函数
?? * @param {Object}? 作用域
?? * @param {Boolean} 是否顺序加载,即加载完一个文件后,再加载下一个,true则顺序加载,默认为false。
?? */
??load : function(fileList, callback, scope, preserveOrder) {
???var scope = scope || this, head = document
?????.getElementsByTagName("head")[0], fragment = document
?????.createDocumentFragment(), numFiles = fileList.length, loadedFiles = 0, me = this;

???/**
??? * preservOrder为true,才会执行该方法。
??? * 根据文件下标逐个加载文件
??? */
???var loadFileIndex = function(index) {
????head.appendChild(me.buildScriptTag(fileList[index],
????????onFileLoaded));
???};

???/**
??? * 当每个文件加载完后,需要执行的回调函数
??? */
???var onFileLoaded = function() {
????loadedFiles++;

????//如果是最后一个文件,执行回调函数,否则加载下一个文件
????if (numFiles == loadedFiles && typeof callback == 'function') {
?????callback.call(scope);
????} else {
?????if (preserveOrder === true) {
??????loadFileIndex(loadedFiles);
?????}
????}
???};
???//如果是按顺序加载,则直接执行loadFileIndex,否则循环加载文件列表
???if (preserveOrder === true) {
????loadFileIndex.call(this, 0);
???} else {
????//load each file (most browsers will do this in parallel)
????for (var index = 0; index < numFiles; index++) {
?????fragment.appendChild(this.buildScriptTag(fileList[index],
?????????onFileLoaded));
????}
????head.appendChild(fragment);
???}
??},

??/**
?? * @private
?? * 创建并返回一个scipt标签
?? * @param {String/Object} 创建script标签文件对象信息对象或者文件名
?? * @param {Function} 可选,当文件加载完后,执行该回调函数
?? * @return {Element} The new script ta
?? */
??buildScriptTag : function(file, callback) {
???var script = document.createElement('script');
???script.type = "text/javascript";
???script.src = file["url"]||file;
???script.id = file["id"]||file["url"]||file;

???//判断浏览器种类,目前只判断IE、FireFox
???if (script.readyState) {
????script.onreadystatechange = function() {
?????if (script.readyState == "loaded"
???????|| script.readyState == "complete") {
??????script.onreadystatechange = null;
??????callback();
?????}
????};
???} else {
????script.onload = callback;
???}

???return script;
??},
??/**
??
*@private
?? * 根据id删除script标签
?? * @param {String} script标签的id
?? * @param {Function} 这个参数为可选,如果需要删除script标签,需要动作则执行该回调函数。
?? * 例如:释放内存等。
?? */
??removeScriptTag : function(id, callback) {
???var existing = doc.getElementById(id);
???if (existing) {
????existing.parentNode.removeChild(existing);
???}
???callback();
??}
?}
}