我的模块加载系统 v4
本版本增加了如下特征:
- 对加载失败时的负向回调支持。由于opera在处理请求无效地址时发出的是致命错误,不能给onerror等捕捉,因此我的负向回调是对它没作用的(测试浏览器为opera11)。但能实现在IE下对script.onerror的模拟,这是我的加载器相对于其他加载器最大的优势,也是本版本最大的亮点。
dom.require(dependList,callback,
/*optional*/
errback)
//依赖列表,正向回调,负向回调
- 如果请求地址无效,会立即中止定时器,防止没完没了的setTimeout。
- 添加更严密的检测防止重复请求。
API与用法见第三版:
//并行加载器 by 司徒正美 2011.3.1 ;;;( function (WIN,DOM,undefined){ var reg_module_name = /(?:^|\/)([^(\/]+)(?=\(|$)/, reg_module_url = /\(([^)]+)\)/, reg_readystate = /loaded|complete/i, scripts = DOM.getElementsByTagName( "script" ), bases = DOM.getElementsByTagName( "base" ), _dom = WIN.dom, dom = { mix : function (target, source ,override) { var i, ride = (override === void 0) || override; for (i in source) { if (ride || !(i in target)) { target[i] = source[i]; } } return target; }, noConflict: function ( ) { //防止命名冲突,请先行引用其他库再引用本框架 WIN.dom = _dom; //这是别人的 return dom; //请赋以其一个命名空间 }, require: function ( /*array or string*/ dependList,callback, /*optional*/ errback){ var self = arguments.callee,moduleNames = [], i = 0, hash = self.loadedModules, reg = reg_module_name ,name, url; if ( typeof dependList === "string" ){ dependList = dependList.split( "," ) } while (url = dependList[i++]){ name = url.match(reg)[1]; if (!hash[name]){ callback.errback = errback || function (){} callback.name = name; callback.url = url; moduleNames.push(name); self.appendScript(callback); } } this .provide(moduleNames,hash,callback) }, define: function (name,dependList,callback){ var hash = this .require.loadedModules, node = DOM.getElementById( "__" +name+ "__" ); if (node){ node[name] += "_loaded" } this .require(dependList, function (){ callback(); hash[name] = 1 }) }, //提供模块 provide: function (array,hash,callback){ var flag = true , i = 0, args = arguments, fn = args.callee, name; while (name = array[i++]){ if (!hash[name]){ flag = false ; break ; } } if (flag){ callback(); } else { callback.timeoutID = setTimeout( function (){ fn.apply( null ,args) },32); } } } dom.mix(dom.require, { loadedModules:{}, requestedUrl:{}, //http://www.cnblogs.com/rubylouvre/archive/2011/02/10/1950940.html getBasePath: function ( /*internal*/ url, /*internal*/ node){ try { a.b.c() } catch (e){ url = e.fileName || e.sourceURL; //针对firefox与safari } if (!url){ node = scripts[scripts.length - 1] url = node.hasAttribute ? node.src : node.getAttribute( 'src' , 4); } url = url.substr( 0, url.lastIndexOf( '/' )); dom.require.getBasePath = function (){ return url; //缓存结果,第一次之后直接返回,再不用计算 } return url; }, appendScript: function (obj, /*internal*/ url){ //处理dom.node(http://www.cnblogs.com/rubylouvre/dom/node.js)的情形 var _url = obj.url.match(reg_module_url), ref = bases[0] || scripts[0], name = obj.name; url = _url && _url[1] ? _url[1] : this .getBasePath()+ "/" + obj.url + ".js" //?timestamp="+1*new Date; if (! this .requestedUrl[url]){ this .requestedUrl[url] = 1; var node = DOM.createElement("script "); node.charset = " utf-8 "; node[name] = name; node.id = " __ "+name+" __ "; node.async = true;//如果 async 属性为 true,则脚本会相对于文档的其余部分异步执行,这样脚本会可以在页面继续解析的过程中来执行。 node.onerror = function(){ clearTimeout(obj.timeoutID); obj.errback(); dom.require.removeScript(this); } node.onload = node.onreadystatechange = function(){ if (-[1,] || reg_readystate.test(this.readyState) ){/*opera的script也存在readyState,但如果请求地址不存在,是不会进入onload回调的*/ if(node[name] !== name+" _loaded"){ clearTimeout(obj.timeoutID); obj.errback(); } dom.require.removeScript( this ); } } node.src = url; //http://paulirish.com/2011/surefire-dom-element-insertion/ ref.parentNode.insertBefore(node,ref ); } }, removeScript: function (node){ //移除临时生成的节点 var parent = node.parentNode if (parent && parent.nodeType === 1){ if (node.clearAttributes) { node.clearAttributes(); } else { node.onload = node.onreadystatechange = node.onerror = null ; } parent.removeChild(node) } } }); //先行取得核心模块的URL dom.require.getBasePath(); window.dom = dom; })( this , this .document) |
如果您觉得此文有帮助,可以打赏点钱给我支付宝1669866773@qq.com ,或扫描二维码


机器瞎学/数据掩埋/模式混淆/人工智障/深度遗忘/神经掉线/计算机幻觉/专注单身二十五年
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库