用于实现EXT单页面的动态js加载.(修复版)

/** * 前端模块异步加载器。 依赖ext的createCallback、createDelegate函数 * var ml = new ModuleLoader({ script : ['/ajaxee/test.js','/ajaxee/test2.js'], style : ['/ajaxee/test.css'], action:{ openPage: function(){alert("3"); }} }); ml.openPage(); //执行函数时才开始加载 * @class moduleLoader * @param {Object} config 配置属性对象 * * @property {Object} action 该模块的处理函数,类型为hash * @property {Array} script 要异步下载的脚本列表 * @property {Array} style 要异步下载的样式列表 * @propety {Boolean} loaded * True表示当前资源已加载到浏览器渲染。此项是为了不会重复下载资源时的判读根据。只读的。Read-Only */ ModuleLoader = function(config) { Ext.apply(this, config); this.loaded = false; // 函数作为值送入createCallback方法,执行moduleLoader的此函数时, // 都会执行moduleDetect, 然后由回调onSuccessHandler来执行action var moduleDetect = this.moduleDetect.createDelegate(this); for (var i in this.action) { var oldFn = this.action[i]; this[i] = moduleDetect.createCallback(oldFn); } }; /** * @private * @param {Fucntion} * onSuccessHandler “按需加载”完成后的回调函数 */ ModuleLoader.prototype = { moduleDetect : function(onSuccessHandler, scope) { if (this.loaded === false) { ModuleLoader.load({ script : this.script, style : this.style, onSuccess : onSuccessHandler }); this.loaded = true; } else { onSuccessHandler.call(scope); } } }; /** * 局部加载JS或CSS文件 * * @static method 静态用法: <code> ModuleLoader.prototype.load({ script : ['/ajaxee/test.js','/ajaxee/test2.js'], style : ['/ajaxee/test.css'], onSuccess : funtion(){} })</code> */ ModuleLoader.load = function(pathConfig) { var dom; var date = new Date(); //每次跟新js文件, 调试用. if (pathConfig.style) { if (!pathConfig.style.pop) pathConfig.style = [pathConfig.style]; for (var i = 0, j = pathConfig.style.length; i < j; i++) { dom = document.createElement("link"); dom.type = "text/css"; dom.rel = "stylesheet" dom.href = pathConfig.style[i]; document.getElementsByTagName("head")[0].appendChild(dom); } } if (pathConfig.script) { if (!pathConfig.script.pop) pathConfig.script = [pathConfig.script]; for (var i = 0, j = pathConfig.script.length; i < j; i++) { dom = document.createElement("script"); dom.src = pathConfig.script[i]+"?"+date; document.getElementsByTagName("head")[0].appendChild(dom); } // 兼容IE、非IE浏览器的判断 dom[Ext.isIE ? "onreadystatechange" : "onload"] = function() { if (this.readyState && this.readyState == "loading") return; dom = null; if (pathConfig.onSuccess){ pathConfig.onSuccess.call(pathConfig.scope, pathConfig.script); } } } };

 

2010年12月1日 更新:

部分解决 IE并行载入js时, 调用错误问题

此动态脚本在IE下遇到一个问题,  原dom[ "onreadystatechange" ] 是在最后一个加载的脚本设置了载入完成的监听.但是由于IE是并行加载js的, 有可能先下载完的脚本要调用其他脚本, 这时就会出现脚本错误.

于是添加了一个bool数组来监控状态:

 

将上函数的最后一个函数修改为

 ModuleLoader.load = function(pathConfig) { var dom; var date = new Date(); // 每次跟新js文件, 调试用. var arrayAlltrue = function(array) { for (var j = 0; j < array.length; j++) { if (array[j] === false) { return false; } } return true; } if (pathConfig.style) { if (!pathConfig.style.pop) pathConfig.style = [pathConfig.style]; for (var i = 0, j = pathConfig.style.length; i < j; i++) { dom = document.createElement("link"); dom.type = "text/css"; dom.rel = "stylesheet" dom.href = pathConfig.style[i]; document.getElementsByTagName("head")[0].appendChild(dom); } } if (pathConfig.script) { if (!pathConfig.script.pop) pathConfig.script = [pathConfig.script]; // 判断是否全部加载 var isAllLoaded = new Array(); for (var i = 0; i < pathConfig.script.length; i++) { isAllLoaded.push(false); dom = document.createElement("script"); dom.src = pathConfig.script[i] + "?" + date; document.getElementsByTagName("head")[0].appendChild(dom); dom.idx = i; dom.isAllLoaded = isAllLoaded; dom.arrayAlltrue = arrayAlltrue; // 为每个js设置加载监听. dom[Ext.isIE ? "onreadystatechange" : "onload"] = function() {// 兼容IE、非IE浏览器的判断 if (this.readyState && this.readyState == "loading") return; this.isAllLoaded[this.idx] = true; dom = null; if (this.arrayAlltrue(this.isAllLoaded)) { if (pathConfig.onSuccess) { pathConfig.onSuccess.call(pathConfig.scope, pathConfig.script); } } } } loaded = null; } };

 

但是IE下还是偶尔会出现错误, 可能是执行顺序上的问题~ 可能加载完后执行的耗时造成.

如果有大大能完美解决IE并行加载js后的执行问题还望指教.

你可能感兴趣的:(Date,function,脚本,ext,IE,stylesheet)