`
ajaxgo
  • 浏览: 18501 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

针对之前bingo发布的一个js loader工具进行的改进【bug已修正】

阅读更多

首先很感谢bingo,用非常新颖的思路,实现了这么一个js的loader工具。往外抛异常阻止函数运行,并在加载完后继续运行caller的做法,让人眼前一亮。不得不佩服js的世界是如此的奇妙。

在阅读bingo的js loader,获得启发的同时,也对其中的代码功能做了一些调整。例如,添加了绑定事件机制,可以预先绑定需要在加载(loaded)完后触发的操作(事件一共有5类)。规范了消息队列的实现,bingo的实现中,把消息队列耦合的太紧密。所以独立实现了一个消息队列,在loader中使用等等。整个代码经过重写,并加了注释,方便爱好者学习和探讨,也希望大家反馈bug。并且允许在include时,设置caller的scope和arguments,这样就可以在一般的函数中,比如实例方法(而不只是在匿名函数)使用include。因为,bingo的实现中,在调用caller时,只是简单的运行caller,如果在有需要作用域和需要参数传递的函数中,会失去原本的作用域和传递进来的参数。

最后,还是非常感谢bingo!

代码如下(代码下载在最后):

js 代码
  1.   
  2. var jsLoader=new function() {   
  3.     /*  
  4.      * const  
  5.      */  
  6.     this.NAMESPACE_TYPE={   
  7.             CLASS:'class',   
  8.             INTERFACE:'interface',   
  9.             OBJECT:'object'   
  10.         };   
  11.     this.LOADMODE_TYPE={   
  12.             PACKAGE:'package',   
  13.             FILE:'file',   
  14.             DYNAMIC:'dynamic'   
  15.         };   
  16.     this.ERROR_LEVEL={   
  17.         INFO:'@jsadk:',   
  18.         DEBUG:'*@jsadk:',   
  19.         FATAL:'!*@jsadk:',         
  20.         THROWS:'^!*@jsadk:'   
  21.     };   
  22.     this.ERRORS={};   
  23.     /*  
  24.      * private member  
  25.      */  
  26.     var _this=this;    
  27.     var _version='1.0a';   
  28.     var _libPath='./';   
  29.     var _errLv=this.ERROR_LEVEL.FATAL;   
  30.     var _loadmode=this.LOADMODE_TYPE.PACKAGE;   
  31.     var _packages={};   
  32.     /*  
  33.      * getter and setter  
  34.      */  
  35.     this.getVersion=function() {   
  36.         return _version;   
  37.     };   
  38.     this.getLibPath=function() {   
  39.         return _libPath;   
  40.     };   
  41.     this.setLibPath=function(libPath) {   
  42.         _libPath=libPath;   
  43.     };   
  44.     this.getLoadMode=function() {   
  45.         return _loadmode;   
  46.     };   
  47.     this.setLoadMode=function(loadmode) {   
  48.         _loadmode=loadmode;   
  49.            
  50.     };   
  51.     this.getErrLevel=function() {   
  52.         return _errLv;   
  53.     }   
  54.     this.setErrLevel=function(level) {   
  55.         _errLv=level;   
  56.     };   
  57.     /*  
  58.      * register packages infos  
  59.      */  
  60.     /**  
  61.      * 增加包信息  
  62.      * @param {Object} root  
  63.      * @param {Hash} pks  
  64.      */  
  65.     var _addPKGs=function(root,pks) {   
  66.         for (var pk in pks) {   
  67.             if (typeof pks[pk]=='string') {   
  68.                 root[pk]=_this.Util.initVar(root[pk],pks[pk]);   
  69.             } else if(typeof pks[pk]=='object') {   
  70.                 root[pk]=_this.Util.initVar(root[pk],{});   
  71.                 _addPKGs(root[pk],pks[pk]);   
  72.             }   
  73.         }   
  74.     };   
  75.     /**  
  76.      * 获得注册的包信息  
  77.      * @param {String|Object} pack  
  78.      */  
  79.     this.getPKGs=function(pack) {   
  80.         return _this.Util.eval(pack,_packages);   
  81.     };   
  82.     /**  
  83.      * 注册包信息  
  84.      * @param {Hash} pkgs  
  85.      * @param {String} ns  
  86.      */  
  87.     this.regPKGs=function(pkgs,ns) {   
  88.         var size=arguments.length;   
  89.         var ns=ns.split('.');   
  90.         var root=_packages;   
  91.         for (var i=0;i
  92.             root=root[ns[i]]=_this.Util.initVar(root[ns[i]],{});   
  93.         }   
  94.         _addPKGs(root,pkgs);   
  95.     };   
  96.     /*  
  97.      * catch the window error  
  98.      */  
  99.     window.onerror=function() {   
  100.         if (arguments[0].indexOf(_errLv)>-1) {   
  101.             return false;   
  102.         } else {   
  103.             return true;   
  104.         }   
  105.     };   
  106. };   
  107.   
  108. with(jsLoader) {   
  109.     /*  
  110.      * utility methods  
  111.      */  
  112.     jsLoader.Util={   
  113.         /**  
  114.          * 一个空函数的引用  
  115.          */  
  116.         emptyFunction:function() {},       
  117.         /**  
  118.          * 在给定的scope中执行代码  
  119.          * @param {String} obj  
  120.          * @param {Object} scope[default=window]  
  121.          */  
  122.         eval:function(obj,scope) {   
  123.             scope=(scope==null)?window:scope;   
  124.             if (typeof obj=='string') {   
  125.                 try {   
  126.                     with(scope) {   
  127.                         obj=eval(obj);   
  128.                     }   
  129.                 } catch (e) {   
  130.                     return undefined;   
  131.                 }   
  132.             }   
  133.             return obj;    
  134.         },   
  135.         /**  
  136.          * 检查在给定的scope中对象是否存在  
  137.          * @param {String|Object} obj  
  138.          * @param {Object} scope[default=window]  
  139.          */  
  140.         exist:function(obj,scope) {   
  141.             return (typeof this.eval(obj,scope)=='undefined'?false:true);   
  142.         },   
  143.         /**  
  144.          * 用给定的值initVal,初始化变量obj,并返回obj。如果obj不为undefined,则直接返回obj  
  145.          * @param {Object} obj  
  146.          * @param {Object} initVal  
  147.          */    
  148.         initVar:function(obj,initVal) {   
  149.             if (typeof obj=='undefined') {   
  150.                 obj=initVal;   
  151.             }   
  152.             return obj;   
  153.         },   
  154.         /**  
  155.          * 用source扩展destination,并返回destination。  
  156.          * fProperty和fValue用来筛选source中的属性和值  
  157.          * @param {Object} destination  
  158.          * @param {Object} source  
  159.          * @param {Function} fProperty(property,destination)[scope=source]  
  160.          * @param {Function} fValue(value,property,destination)[scope=source]  
  161.          */  
  162.         extend:function(destination,source,fProperty,fValue) {   
  163.             for (var property in source) {   
  164.                 var _property=(fProperty || Util.emptyFunction).call(source,property,destination);   
  165.                 if (_property!=false) {   
  166.                     var _value=(fValue!=null?   
  167.                                     fValue.call(source,source[property],property,destination):   
  168.                                     source[property]);   
  169.                     destination[typeof _property=='string'?_property:property]=_value;   
  170.                 }   
  171.             }   
  172.             return destination;   
  173.         }   
  174.     };   
  175.     /*  
  176.      * extends Array  
  177.      */  
  178.     (function() {   
  179.         Util.extend(Array.prototype,{   
  180.             first:function() {   
  181.                 return this[0];   
  182.             },   
  183.             last:function() {   
  184.                 return this[this.length-1];   
  185.             },   
  186.             /**  
  187.              * 给出element在队列中所处的位置索引(第一个),如果不存在则返回-1。参数struct为true是进行严格比较  
  188.              * @param {Object} element  
  189.              * @param {Boolean} struct[default=false]  
  190.              */  
  191.             indexOf:function(element,struct) {   
  192.                 var size=this.length;   
  193.                 for (var i=0;i
  194.                     if ((struct && this[i]===element) ||    
  195.                             (!struct && this[i]==element)) {   
  196.                         break;     
  197.                     }    
  198.                 }   
  199.                 return (i==size?-1:i);   
  200.             },   
  201.             /**  
  202.              * 在索引index处插入元素element1,element2,....  
  203.              * @param {Number} index  
  204.              */  
  205.             insertAt:function(index) {   
  206.                 var args=[index,0];   
  207.                 var size=arguments.length;   
  208.                 for (var i=1;i
  209.                     args.push(arguments[i]);   
  210.                 }   
  211.                 this.splice.apply(this,args);   
  212.             },   
  213.             /**  
  214.              * 删除索引index处的size个元素,并返回删除的元素数组  
  215.              * @param {Number} index  
  216.              * @param {Number} size[opt=1]  
  217.              */  
  218.             deleteAt:function(index,size) {   
  219.                 result=this.splice(index,size || 1);   
  220.                 return result;     
  221.             },   
  222.             /**  
  223.              * 清空队列  
  224.              */  
  225.             clear:function() {   
  226.                 this.length=0;   
  227.             }   
  228.         });   
  229.     })();   
  230.     /**  
  231.      * 事件队列,用于注册和注销事件。并触发对应事件  
  232.      */  
  233.     jsLoader.EventQueue=(function() {   
  234.         Util.extend(ERRORS,{   
  235.             'EventQueue.NO_SUCH_EVENT':ERROR_LEVEL.DEBUG+'no such a event',   
  236.             'EventQueue.ALEADY_EXIST':ERROR_LEVEL.DEBUG+'the message is already exsited!'   
  237.         });   
  238.         var constructor=function(event) {   
  239.             this._queue={};   
  240.             this.EVENT={};   
  241.             for (var e in event) {   
  242.                 this.EVENT[event[e]]=true;   
  243.                 this._queue[event[e]]=[];   
  244.             }   
  245.         };   
  246.         Util.extend(constructor.prototype,{   
  247.             /**  
  248.              * 触发队列中,对应事件event的消息。参数dispose为ture时,将在触发完后删除该事件的所有消息。  
  249.              * @param {String} event  
  250.              * @param {Boolean} dispose[default=false]  
  251.              * @param {Array} args[default=[]]  
  252.              */  
  253.             dispatch:function(event,dispose,args) {   
  254.                 if (this.EVENT[event]) {   
  255.                     var messages=this._queue[event];   
  256.                     var size=messages.length;   
  257.                     try {   
  258.                         for (var i=0;i
  259.                             messages[i++].apply(messages[i++],messages[i++].concat(args || []));   
  260.                         }   
  261.                     } catch(e) {   
  262.                         throw new Error(ERROR_LEVEL.DEBUG+e.message);   
  263.                     } finally {   
  264.                         if (dispose) {   
  265.                             this._queue[event].clear();   
  266.                         }   
  267.                     }   
  268.                 } else {   
  269.                     throw new Error(ERRORS['EventQueue.NO_SUCH_EVENT']+':'+event);   
  270.                 }   
  271.             },   
  272.             /**  
  273.              * 注册事件event的消息message。scope和args参数指定了消息调用时的作用域和参数。  
  274.              * @param {String} event  
  275.              * @param {Function} message  
  276.              * @param {Object} scope[default=window]  
  277.              * @param {Array} args[default=[]]  
  278.              */  
  279.             on:function(event,message,scope,args) {   
  280.                 if (this.EVENT[event]) {   
  281.                     if (this._queue[event].indexOf(message)==-1) {   
  282.                         this._queue[event].push(message);   
  283.                         this._queue[event].push(scope || window);   
  284.                         this._queue[event].push(args || []);   
  285.                     } else {   
  286.                         throw new Error(ERRORS['EventQueue.ALEADY_EXIST']+':'+event);   
  287.                     }          
  288.                 } else {   
  289.                     throw new Error(ERRORS['EventQueue.NO_SUCH_EVENT']+':'+event);   
  290.                 }   
  291.             },   
  292.             /**  
  293.              * 注销事件event的小心message  
  294.              * @param {String} event  
  295.              * @param {Function} message  
  296.              */  
  297.             un:function(event,message) {   
  298.                 var index;   
  299.                 if (this.EVENT[event] && (index=this._queue[event].indexOf(message))!=-1) {   
  300.                     this._queue[event].deleteAt(index,3);   
  301.                 } else {   
  302.                     throw new Error(ERRORS['EventQueue.NO_SUCH_EVENT']+':'+event);   
  303.                 }                  
  304.             }   
  305.         });   
  306.         return constructor;   
  307.     })();   
  308.     /*  
  309.      * a class of message queue, used to invoke messages orderly  
  310.      */  
  311.     jsLoader.MessageQueue=(function() {    
  312.         var constructor=function() {   
  313.             this._queue=[];   
  314.             this._listened=null;   
  315.         }   
  316.         Util.extend(constructor.prototype,{   
  317.             /**  
  318.              * 队列监听器,识别队列中是否有可以产生的消息  
  319.              */  
  320.             _listen:function() {   
  321.                 var _this=this;                
  322.                 if (this._listened) {   
  323.                     if (this._queue.length==0) {   
  324.                         setTimeout(function() {   
  325.                             _this._listen()   
  326.                         },500);   
  327.                     } else {   
  328.                         this.inform();   
  329.                     }   
  330.                 }   
  331.             },   
  332.             /**  
  333.              * 启动监听器  
  334.              */  
  335.             startListen:function() {   
  336.                 this._listened=true;   
  337.                 this._listen();    
  338.             },   
  339.             /**  
  340.              * 停止监听器  
  341.              */  
  342.             stopListen:function() {   
  343.                 this._listened=false;   
  344.             },   
  345.             /**  
  346.              * 通知消息队列,另起产生队列头部的一个消息  
  347.              */  
  348.             inform:function() {   
  349.                 if (this._queue.length==0) {   
  350.                     this._listen();   
  351.                     return;   
  352.                 } else {   
  353.                     var message=this._queue.shift();   
  354.                     var scope=this._queue.shift();   
  355.                     var args=this._queue.shift();   
  356.                     try {   
分享到:
评论
7 楼 rain16881 2008-04-21  
我用了之后是可以按自己想的顺序加载了..

不过.性能是一个好大的问题.

加上..我在js 的有调用的..一个也不要用.
6 楼 rain16881 2008-04-21  
有的ext desktop就有一个js加载顺序的问题.

希望能用你的js loader解决
5 楼 brull 2008-01-14  
<div class='quote_title'>ajaxgo 写道</div><div class='quote_div'><div class='quote_title'>brull 写道</div><div class='quote_div'><div class='quote_div'>呵呵,原来在12月份就有这么个东西发布了呢,看样子不错,不过代码没仔细看。对于bingo我也很长时间没空去进一步完善了,希望来年来完善一下。冒味问下,你是与狼共舞?</div></div><p> </p><p>我不是与狼共舞哦,呵呵,不好意思</p></div><br/>那看来对这个东西感兴趣的人还是有一些的,我也感到比较欣慰,再接再厉
4 楼 ajaxgo 2008-01-14  
<div class='quote_title'>brull 写道</div><div class='quote_div'><div class='quote_div'>呵呵,原来在12月份就有这么个东西发布了呢,看样子不错,不过代码没仔细看。对于bingo我也很长时间没空去进一步完善了,希望来年来完善一下。冒味问下,你是与狼共舞?</div></div><p> </p><p>我不是与狼共舞哦,呵呵,不好意思</p>
3 楼 ajaxgo 2008-01-14  
sun2grit 写道
能举几个简单的调用示例吗?


下载的代码里面有示例
2 楼 brull 2008-01-12  
<div class='quote_title'>ajaxgo 写道</div><div class='quote_div'><p>首先很感谢bingo,用非常新颖的思路,实现了这么一个js的loader工具。往外抛异常阻止函数运行,并在加载完后继续运行caller的做法,让人眼前一亮。不得不佩服js的世界是如此的奇妙。</p><p>在阅读bingo的js loader,获得启发的同时,也对其中的代码功能做了一些调整。例如,添加了绑定事件机制,可以预先绑定需要在加载(loaded)完后触发的操作(事件一共有5类)。规范了消息队列的实现,bingo的实现中,把消息队列耦合的太紧密。所以独立实现了一个消息队列,在loader中使用等等。整个代码经过重写,并加了注释,方便爱好者学习和探讨,也希望大家反馈bug。并且允许在include时,设置caller的scope和arguments,这样就可以在一般的函数中,比如实例方法(而不只是在匿名函数)使用include。因为,bingo的实现中,在调用caller时,只是简单的运行caller,如果在有需要作用域和需要参数传递的函数中,会失去原本的作用域和传递进来的参数。</p><p>最后,还是非常感谢bingo!</p><p>代码如下(代码下载在最后):</p><div class='code_title'>js 代码</div><div class='dp-highlighter'><ol class='dp-c'><li class='alt'><span><span>  </span></span> </li><li><span class='keyword'>var</span><span> jsLoader=</span><span class='keyword'>new</span><span> </span><span class='keyword'>function</span><span>() {   </span> </li><li class='alt'><span>    </span><span class='comment'>/* </span>  </li><li><span><span class='comment'>     * const </span> </span> </li><li class='alt'><span><span class='comment'>     */</span><span>  </span></span> </li><li><span>    </span><span class='keyword'>this</span><span>.NAMESPACE_TYPE={   </span> </li><li class='alt'><span>            CLASS:'</span><span class='keyword'>class</span><span>',   </span> </li><li><span>            INTERFACE:'</span><span class='keyword'>interface</span><span>',   </span> </li><li class='alt'><span>            OBJECT:'object'   </span> </li><li><span>        };   </span> </li><li class='alt'><span>    </span><span class='keyword'>this</span><span>.LOADMODE_TYPE={   </span> </li><li><span>            PACKAGE:'</span><span class='keyword'>package</span><span>',   </span> </li><li class='alt'><span>            FILE:'file',   </span> </li><li><span>            DYNAMIC:'dynamic'   </span> </li><li class='alt'><span>        };   </span> </li><li><span>    </span><span class='keyword'>this</span><span>.ERROR_LEVEL={   </span> </li><li class='alt'><span>        INFO:'@jsadk:',   </span> </li><li><span>        DEBUG:'*@jsadk:',   </span> </li><li class='alt'><span>        FATAL:'!*@jsadk:',         </span> </li><li><span>        THROWS:'^!*@jsadk:'   </span> </li><li class='alt'><span>    };   </span> </li><li><span>    </span><span class='keyword'>this</span><span>.ERRORS={};   </span> </li><li class='alt'><span>    </span><span class='comment'>/* </span>  </li><li><span><span class='comment'>     * private member </span> </span> </li><li class='alt'><span><span class='comment'>     */</span><span>  </span></span> </li><li><span>    </span><span class='keyword'>var</span><span> _this=</span><span class='keyword'>this</span><span>;    </span> </li><li class='alt'><span>    </span><span class='keyword'>var</span><span> _version='1.0a';   </span> </li><li><span>    </span><span class='keyword'>var</span><span> _libPath='./';   </span> </li><li class='alt'><span>    </span><span class='keyword'>var</span><span> _errLv=</span><span class='keyword'>this</span><span>.ERROR_LEVEL.FATAL;   </span> </li><li><span>    </span><span class='keyword'>var</span><span> _loadmode=</span><span class='keyword'>this</span><span>.LOADMODE_TYPE.PACKAGE;   </span> </li><li class='alt'><span>    </span><span class='keyword'>var</span><span> _packages={};   </span> </li><li><span>    </span><span class='comment'>/* </span>  </li><li class='alt'><span><span class='comment'>     * getter and setter </span> </span> </li><li><span><span class='comment'>     */</span><span>  </span></span> </li><li class='alt'><span>    </span><span class='keyword'>this</span><span>.getVersion=</span><span class='keyword'>function</span><span>() {   </span> </li><li><span>        </span><span class='keyword'>return</span><span> _version;   </span> </li><li class='alt'><span>    };   </span> </li><li><span>    </span><span class='keyword'>this</span><span>.getLibPath=</span><span class='keyword'>function</span><span>() {   </span> </li><li class='alt'><span>        </span><span class='keyword'>return</span><span> _libPath;   </span> </li><li><span>    };   </span> </li><li class='alt'><span>    </span><span class='keyword'>this</span><span>.setLibPath=</span><span class='keyword'>function</span><span>(libPath) {   </span> </li><li><span>        _libPath=libPath;   </span> </li><li class='alt'><span>    };   </span> </li><li><span>    </span><span class='keyword'>this</span><span>.getLoadMode=</span><span class='keyword'>function</span><span>() {   </span> </li><li class='alt'><span>        </span><span class='keyword'>return</span><span> _loadmode;   </span> </li><li><span>    };   </span> </li><li class='alt'><span>    </span><span class='keyword'>this</span><span>.setLoadMode=</span><span class='keyword'>function</span><span>(loadmode) {   </span> </li><li><span>        _loadmode=loadmode;   </span> </li><li class='alt'><span>           </span> </li><li><span>    };   </span> </li><li class='alt'><span>    </span><span class='keyword'>this</span><span>.getErrLevel=</span><span class='keyword'>function</span><span>() {   </span> </li><li><span>        </span><span class='keyword'>return</span><span> _errLv;   </span> </li><li class='alt'><span>    }   </span> </li><li><span>    </span><span class='keyword'>this</span><span>.setErrLevel=</span><span class='keyword'>function</span><span>(level) {   </span> </li><li class='alt'><span>        _errLv=level;   </span> </li><li><span>    };   </span> </li><li class='alt'><span>    </span><span class='comment'>/* </span>  </li><li><span><span class='comment'>     * register packages infos </span> </span> </li><li class='alt'><span><span class='comment'>     */</span><span>  </span></span> </li><li><span>    </span><span class='comment'>/** </span>  </li><li class='alt'><span><span class='comment'>     * 增加包信息 </span> </span> </li><li><span><span class='comment'>     * @param {Object} root </span> </span> </li><li class='alt'><span><span class='comment'>     * @param {Hash} pks </span> </span> </li><li><span><span class='comment'>     */</span><span>  </span></span> </li><li class='alt'><span>    </span><span class='keyword'>var</span><span> _addPKGs=</span><span class='keyword'>function</span><span>(root,pks) {   </span> </li><li><span>        </span><span class='keyword'>for</span><span> (</span><span class='keyword'>var</span><span> pk </span><span class='keyword'>in</span><span> pks) {   </span> </li><li class='alt'><span>            </span><span class='keyword'>if</span><span> (</span><span class='keyword'>typeof</span><span> pks[pk]=='string') {   </span> </li><li><span>                root[pk]=_this.Util.initVar(root[pk],pks[pk]);   </span> </li><li class='alt'><span>            } </span><span class='keyword'>else</span><span> </span><span class='keyword'>if</span><span>(</span><span class='keyword'>typeof</span><span> pks[pk]=='object') {   </span> </li><li><span>                root[pk]=_this.Util.initVar(root[pk],{});   </span> </li><li class='alt'><span>                _addPKGs(root[pk],pks[pk]);   </span> </li><li><span>            }   </span> </li><li class='alt'><span>        }   </span> </li><li><span>    };   </span> </li><li class='alt'><span>    </span><span class='comment'>/** </span>  </li><li><span><span class='comment'>     * 获得注册的包信息 </span> </span> </li><li class='alt'><span><span class='comment'>     * @param {String|Object} pack </span> </span> </li><li><span><span class='comment'>     */</span><span>  </span></span> </li><li class='alt'><span>    </span><span class='keyword'>this</span><span>.getPKGs=</span><span class='keyword'>function</span><span>(pack) {   </span> </li><li><span>        </span><span class='keyword'>return</span><span> _this.Util.eval(pack,_packages);   </span> </li><li class='alt'><span>    };   </span> </li><li><span>    </span><span class='comment'>/** </span>  </li><li class='alt'><span><span class='comment'>     * 注册包信息 </span> </span> </li><li><span><span class='comment'>     * @param {Hash} pkgs </span> </span> </li><li class='alt'><span><span class='comment'>     * @param {String} ns </span> </span> </li><li><span><span class='comment'>     */</span><span>  </span></span> </li><li class='alt'><span>    </span><span class='keyword'>this</span><span>.regPKGs=</span><span class='keyword'>function</span><span>(pkgs,ns) {   </span> </li><li><span>        </span><span class='keyword'>var</span><span> size=arguments.length;   </span> </li><li class='alt'><span>        </span><span class='keyword'>var</span><span> ns=ns.split(</span><span class='string'>'.'</span><span>);   </span> </li><li><span>        </span><span class='keyword'>var</span><span> root=_packages;   </span> </li><li class='alt'><span>        </span><span class='keyword'>for</span><span> (</span><span class='keyword'>var</span><span> i=0;i </span></li><li><span>            root=root[ns[i]]=_this.Util.initVar(root[ns[i]],{});   </span> </li><li class='alt'><span>        }   </span> </li><li><span>        _addPKGs(root,pkgs);   </span> </li><li class='alt'><span>    };   </span> </li><li><span>    </span><span class='comment'>/* </span>  </li><li class='alt'><span><span class='comment'>     * catch the window error </span> </span> </li><li><span><span class='comment'>     */</span><span>  </span></span> </li><li class='alt'><span>    window.onerror=</span><span class='keyword'>function</span><span>() {   </span> </li><li><span>        </span><span class='keyword'>if</span><span> (arguments[0].indexOf(_errLv)&gt;-1) {   </span> </li><li class='alt'><span>            </span><span class='keyword'>return</span><span> </span><span class='keyword'>false</span><span>;   </span> </li><li><span>        } </span><span class='keyword'>else</span><span> {   </span> </li><li class='alt'><span>            </span><span class='keyword'>return</span><span> </span><span class='keyword'>true</span><span>;   </span> </li><li><span>        }   </span> </li><li class='alt'><span>    };   </span> </li><li><span>};   </span> </li><li class='alt'><span>  </span> </li><li><span class='keyword'>with</span><span>(jsLoader) {   </span> </li><li class='alt'><span>    </span><span class='comment'>/* </span>  </li><li><span><span class='comment'>     * utility methods </span> </span> </li><li class='alt'><span><span class='comment'>     */</span><span>  </span></span> </li><li><span>    jsLoader.Util={   </span> </li><li class='alt'><span>        </span><span class='comment'>/** </span>  </li><li><span><span class='comment'>         * 一个空函数的引用 </span> </span> </li><li class='alt'><span><span class='comment'>         */</span><span>  </span></span> </li><li><span>        emptyFunction:</span><span class='keyword'>function</span><span>() {},       </span> </li><li class='alt'><span>        </span><span class='comment'>/** </span>  </li><li><span><span class='comment'>         * 在给定的scope中执行代码 </span> </span> </li><li class='alt'><span><span class='comment'>         * @param {String} obj </span> </span> </li><li><span><span class='comment'>         * @param {Object} scope[default=window] </span> </span> </li><li class='alt'><span><span class='comment'>         */</span><span>  </span></span> </li><li><span>        eval:</span><span class='keyword'>function</span><span>(obj,scope) {   </span> </li><li class='alt'><span>            scope=(scope==</span><span class='keyword'>null</span><span>)?window:scope;   </span> </li><li><span>            </span><span class='keyword'>if</span><span> (</span><span class='keyword'>typeof</span><span> obj=='string') {   </span> </li><li class='alt'><span>                </span><span class='keyword'>try</span><span> {   </span> </li><li><span>                    </span><span class='keyword'>with</span><span>(scope) {   </span> </li><li class='alt'><span>                        obj=eval(obj);   </span> </li><li><span>                    }   </span> </li><li class='alt'><span>                } </span><span class='keyword'>catch</span><span> (e) {   </span> </li><li><span>                    </span><span class='keyword'>return</span><span> undefined;   </span> </li><li class='alt'><span>                }   </span> </li><li><span>            }   </span> </li><li class='alt'><span>            </span><span class='keyword'>return</span><span> obj;    </span> </li><li><span>        },   </span> </li><li class='alt'><span>        </span><span class='comment'>/** </span>  </li><li><span><span class='comment'>         * 检查在给定的scope中对象是否存在 </span> </span> </li><li class='alt'><span><span class='comment'>         * @param {String|Object} obj </span> </span> </li><li><span><span class='comment'>         * @param {Object} scope[default=window] </span> </span> </li><li class='alt'><span><span class='comment'>         */</span><span>  </span></span> </li><li><span>        exist:</span><span class='keyword'>function</span><span>(obj,scope) {   </span> </li><li class='alt'><span>            </span><span class='keyword'>return</span><span> (</span><span class='keyword'>typeof</span><span> </span><span class='keyword'>this</span><span>.eval(obj,scope)=='undefined'?</span><span class='keyword'>false</span><span>:</span><span class='keyword'>true</span><span>);   </span> </li><li><span>        },   </span> </li><li class='alt'><span>        </span><span class='comment'>/** </span>  </li><li><span><span class='comment'>         * 用给定的值initVal,初始化变量obj,并返回obj。如果obj不为undefined,则直接返回obj </span> </span> </li><li class='alt'><span><span class='comment'>         * @param {Object} obj </span> </span> </li><li><span><span class='comment'>         * @param {Object} initVal </span> </span> </li><li class='alt'><span><span class='comment'>         */</span><span>    </span></span> </li><li><span>        initVar:</span><span class='keyword'>function</span><span>(obj,initVal) {   </span> </li><li class='alt'><span>            </span><span class='keyword'>if</span><span> (</span><span class='keyword'>typeof</span><span> obj=='undefined') {   </span> </li><li><span>                obj=initVal;   </span> </li><li class='alt'><span>            }   </span> </li><li><span>            </span><span class='keyword'>return</span><span> obj;   </span> </li><li class='alt'><span>        },   </span> </li><li><span>        </span><span class='comment'>/** </span>  </li><li class='alt'><span><span class='comment'>         * 用source扩展destination,并返回destination。 </span> </span> </li><li><span><span class='comment'>         * fProperty和fValue用来筛选source中的属性和值 </span> </span> </li><li class='alt'><span><span class='comment'>         * @param {Object} destination </span> </span> </li><li><span><span class='comment'>         * @param {Object} source </span> </span> </li><li class='alt'><span><span class='comment'>         * @param {Function} fProperty(property,destination)[scope=source] </span> </span> </li><li><span><span class='comment'>         * @param {Function} fValue(value,property,destination)[scope=source] </span> </span> </li><li class='alt'><span><span class='comment'>         */</span><span>  </span></span> </li><li><span>        extend:</span><span class='keyword'>function</span><span>(destination,source,fProperty,fValue) {   </span> </li><li class='alt'><span>            </span><span class='keyword'>for</span><span> (</span><span class='keyword'>var</span><span> property </span><span class='keyword'>in</span><span> source) {   </span> </li><li><span>                </span><span class='keyword'>var</span><span> _property=(fProperty || Util.emptyFunction).call(source,property,destination);   </span> </li><li class='alt'><span>                </span><span class='keyword'>if</span><span> (_property!=</span><span class='keyword'>false</span><span>) {   </span> </li><li><span>                    </span><span class='keyword'>var</span><span> _value=(fValue!=</span><span class='keyword'>null</span><span>?   </span> </li><li class='alt'><span>                                    fValue.call(source,source[property],property,destination):   </span> </li><li><span>                                    source[property]);   </span> </li><li class='alt'><span>                    destination[</span><span class='keyword'>typeof</span><span> _property=='string'?_property:property]=_value;   </span> </li><li><span>                }   </span> </li><li class='alt'><span>            }   </span> </li><li><span>            </span><span class='keyword'>return</span><span> destination;   </span> </li><li class='alt'><span>        }   </span> </li><li><span>    };   </span> </li><li class='alt'><span>    </span><span class='comment'>/* </span>  </li><li><span><span class='comment'>     * extends Array </span> </span> </li><li class='alt'><span><span class='comment'>     */</span><span>  </span></span> </li><li><span>    (</span><span class='keyword'>function</span><span>() {   </span> </li><li class='alt'><span>        Util.extend(Array.prototype,{   </span> </li><li><span>            first:</span><span class='keyword'>function</span><span>() {   </span> </li><li class='alt'><span>                </span><span class='keyword'>return</span><span> </span><span class='keyword'>this</span><span>[0];   </span> </li><li><span>            },   </span> </li><li class='alt'><span>            last:</span><span class='keyword'>function</span><span>() {   </span> </li><li><span>                </span><span class='keyword'>return</span><span> </span><span class='keyword'>this</span><span>[</span><span class='keyword'>this</span><span>.length-1];   </span> </li><li class='alt'><span>            },   </span> </li><li><span>            </span><span class='comment'>/** </span>  </li><li class='alt'><span><span class='comment'>             * 给出element在队列中所处的位置索引(第一个),如果不存在则返回-1。参数struct为true是进行严格比较 </span> </span> </li><li><span><span class='comment'>             * @param {Object} element </span> </span> </li><li class='alt'><span><span class='comment'>             * @param {Boolean} struct[default=false] </span> </span> </li><li><span><span class='comment'>             */</span><span>  </span></span> </li><li class='alt'><span>            indexOf:</span><span class='keyword'>function</span><span>(element,struct) {   </span> </li><li><span>                </span><span class='keyword'>var</span><span> size=</span><span class='keyword'>this</span><span>.length;   </span> </li><li class='alt'><span>                </span><span class='keyword'>for</span><span> (</span><span class='keyword'>var</span><span> i=0;i </span></li><li><span>                    </span><span class='keyword'>if</span><span> ((struct &amp;&amp; </span><span class='keyword'>this</span><span>[i]===element) ||    </span> </li><li class='alt'><span>                            (!struct &amp;&amp; </span><span class='keyword'>this</span><span>[i]==element)) {   </span> </li><li><span>                        </span><span class='keyword'>break</span><span>;     </span> </li><li class='alt'><span>                    }    </span> </li><li><span>                }   </span> </li><li class='alt'><span>                </span><span class='keyword'>return</span><span> (i==size?-1:i);   </span> </li><li><span>            },   </span> </li><li class='alt'><span>            </span><span class='comment'>/** </span>  </li><li><span><span class='comment'>             * 在索引index处插入元素element1,element2,.... </span> </span> </li><li class='alt'><span><span class='comment'>             * @param {Number} index </span> </span> </li><li><span><span class='comment'>             */</span><span>  </span></span> </li><li class='alt'><span>            insertAt:</span><span class='keyword'>function</span><span>(index) {   </span> </li><li><span>                </span><span class='keyword'>var</span><span> args=[index,0];   </span> </li><li class='alt'><span>                </span><span class='keyword'>var</span><span> size=arguments.length;   </span> </li><li><span>                </span><span class='keyword'>for</span><span> (</span><span class='keyword'>var</span><span> i=1;i </span></li><li class='alt'><span>                    args.push(arguments[i]);   </span> </li><li><span>                }   </span> </li><li class='alt'><span>                </span><span class='keyword'>this</span><span>.splice.apply(</span><span class='keyword'>this</span><span>,args);   </span> </li><li><span>            },   </span> </li><li class='alt'><span>            </span><span class='comment'>/** </span>  </li><li><span><span class='comment'>             * 删除索引index处的size个元素,并返回删除的元素数组 </span> </span> </li><li class='alt'><span><span class='comment'>             * @param {Number} index </span> </span> </li><li><span><span class='comment'>             * @param {Number} size[opt=1] </span> </span> </li><li class='alt'><span><span class='comment'>             */</span><span>  </span></span> </li><li><span>            deleteAt:</span><span class='keyword'>function</span><span>(index,size) {   </span> </li><li class='alt'><span>                result=</span><span class='keyword'>this</span><span>.splice(index,size || 1);   </span> </li><li><span>                </span><span class='keyword'>return</span><span> result;     </span> </li><li class='alt'><span>            },   </span> </li><li><span>            </span><span class='comment'>/** </span>  </li><li class='alt'><span><span class='comment'>             * 清空队列 </span> </span> </li><li><span><span class='comment'>             */</span><span>  </span></span> </li><li class='alt'><span>            clear:</span><span class='keyword'>function</span><span>() {   </span> </li><li><span>                </span><span class='keyword'>this</span><span>.length=0;   </span> </li><li class='alt'><span>            }   </span> </li><li><span>        });   </span> </li><li class='alt'><span>    })();   </span> </li><li><span>    </span><span class='comment'>/** </span>  </li><li class='alt'><span><span class='comment'>     * 事件队列,用于注册和注销事件。并触发对应事件 </span> </span> </li><li><span><span class='comment'>     */</span><span>  </span></span> </li><li class='alt'><span>    jsLoader.EventQueue=(</span><span class='keyword'>function</span><span>() {   </span> </li><li><span>        Util.extend(ERRORS,{   </span> </li><li class='alt'><span>            'EventQueue.NO_SUCH_EVENT':ERROR_LEVEL.DEBUG+'no such a event',   </span> </li><li><span>            'EventQueue.ALEADY_EXIST':ERROR_LEVEL.DEBUG+'the message is already exsited!'   </span> </li><li class='alt'><span>        });   </span> </li><li><span>        </span><span class='keyword'>var</span><span> constructor=</span><span class='keyword'>function</span><span>(event) {   </span> </li><li class='alt'><span>            </span><span class='keyword'>this</span><span>._queue={};   </span> </li><li><span>            </span><span class='keyword'>this</span><span>.EVENT={};   </span> </li><li class='alt'><span>            </span><span class='keyword'>for</span><span> (</span><span class='keyword'>var</span><span> e </span><span class='keyword'>in</span><span> event) {   </span> </li><li><span>                </span><span class='keyword'>this</span><span>.EVENT[event[e]]=</span><span class='keyword'>true</span><span>;   </span> </li><li class='alt'><span>                </span><span class='keyword'>this</span><span>._queue[event[e]]=[];   </span> </li><li><span>            }   </span> </li><li class='alt'><span>        };   </span> </li><li><span>        Util.extend(constructor.prototype,{   </span> </li><li class='alt'><span>            </span><span class='comment'>/** </span>  </li><li><span><span class='comment'>             * 触发队列中,对应事件event的消息。参数dispose为ture时,将在触发完后删除该事件的所有消息。 </span> </span> </li><li class='alt'><span><span class='comment'>             * @param {String} event </span> </span> </li><li><span><span class='comment'>             * @param {Boolean} dispose[default=false] </span> </span> </li><li class='alt'><span><span class='comment'>             * @param {Array} args[default=[]] </span> </span> </li><li><span><span class='comment'>             */</span><span>  </span></span> </li><li class='alt'><span>            dispatch:</span><span class='keyword'>function</span><span>(event,dispose,args) {   </span> </li><li><span>                </span><span class='keyword'>if</span><span> (</span><span class='keyword'>this</span><span>.EVENT[event]) {   </span> </li><li class='alt'><span>                    </span><span class='keyword'>var</span><span> messages=</span><span class='keyword'>this</span><span>._queue[event];   </span> </li><li><span>                    </span><span class='keyword'>var</span><span> size=messages.length;   </span> </li><li class='alt'><span>                    </span><span class='keyword'>try</span><span> {   </span> </li><li><span>                        </span><span class='keyword'>for</span><span> (</span><span class='keyword'>var</span><span> i=0;i </span></li><li class='alt'><span>                            messages[i++].apply(messages[i++],messages[i++].concat(args || []));   </span> </li><li><span>                        }   </span> </li><li class='alt'><span>                    } </span><span class='keyword'>catch</span><span>(e) {   </span> </li><li><span>                        </span><span class='keyword'>throw</span><span> </span><span class='keyword'>new</span><span> Error(ERROR_LEVEL.DEBUG+e.message);   </span> </li><li class='alt'><span>                    } </span><span class='keyword'>finally</span><span> {   </span> </li><li><span>                        </span><span class='keyword'>if</span><span> (dispose) {   </span> </li><li class='alt'><span>                            </span><span class='keyword'>this</span><span>._queue[event].clear();   </span> </li><li><span>                        }   </span> </li><li class='alt'><span>                    }   </span> </li><li><span>                } </span><span class='keyword'>else</span><span> {   </span> </li><li class='alt'><span>                    </span><span class='keyword'>throw</span><span> </span><span class='keyword'>new</span><span> Error(ERRORS['EventQueue.NO_SUCH_EVENT']+':'+event);   </span> </li><li><span>                }   </span> </li><li class='alt'><span>            },   </span> </li><li><span>            </span><span class='comment'>/** </span>  </li><li class='alt'><span><span class='comment'>             * 注册事件event的消息message。scope和args参数指定了消息调用时的作用域和参数。 </span> </span> </li><li><span><span class='comment'>             * @param {String} event </span> </span> </li><li class='alt'><span><span class='comment'>             * @param {Function} message </span> </span> </li><li><span><span class='comment'>             * @param {Object} scope[default=window] </span> </span> </li><li class='alt'><span><span class='comment'>             * @param {Array} args[default=[]] </span> </span> </li><li><span><span class='comment'>             */</span><span>  </span></span> </li><li class='alt'><span>            on:</span><span class='keyword'>function</span><span>(event,message,scope,args) {   </span> </li><li><span>                </span><span class='keyword'>if</span><span> (</span><span class='keyword'>this</span><span>.EVENT[event]) {   </span> </li><li class='alt'><span>                    </span><span class='keyword'>if</span><span> (</span><span class='keyword'>this</span><span>._queue[event].indexOf(message)==-1) {   </span> </li><li><span>                        </span><span class='keyword'>this</span><span>._queue[event].push(message);   </span> </li><li class='alt'><span>                        </span><span class='keyword'>this</span><span>._queue[event].push(scope || window);   </span> </li><li><span>                        </span><span class='keyword'>this</span><span>._queue[event].push(args || []);   </span> </li><li class='alt'><span>                    } </span><span class='keyword'>else</span><span> {   </span> </li><li><span>                        </span><span class='keyword'>throw</span><span> </span><span class='keyword'>new</span><span> Error(ERRORS['EventQueue.ALEADY_EXIST']+':'+event);   </span> </li><li class='alt'><span>                    }          </span> </li><li><span>                } </span><span class='keyword'>else</span><span> {   </span> </li><li class='alt'><span>                    </span><span class='keyword'>throw</span><span> </span><span class='keyword'>new</span><span> Error(ERRORS['EventQueue.NO_SUCH_EVENT']+':'+event);   </span> </li><li><span>                }   </span> </li><li class='alt'><span>            },   </span> </li><li><span>            </span><span class='comment'>/** </span>  </li><li class='alt'><span><span class='comment'>             * 注销事件event的小心message </span> </span> </li><li><span><span class='comment'>             * @param {String} event </span> </span> </li><li class='alt'><span><span class='comment'>             * @param {Function} message </span> </span> </li><li><span><span class='comment'>             */</span><span>  </span></span> </li><li class='alt'><span>            un:</span><span class='keyword'>function</span><span>(event,message) {   </span> </li><li><span>                </span><span class='keyword'>var</span><span> index;   </span> </li><li class='alt'><span>                </span><span class='keyword'>if</span><span> (</span><span class='keyword'>this</span><span>.EVENT[event] &amp;&amp; (index=</span><span class='keyword'>this</span><span>._queue[event].indexOf(message))!=-1) {   </span> </li><li><span>                    </span><span class='keyword'>this</span><span>._queue[event].deleteAt(index,3);   </span> </li><li class='alt'><span>                } </span><span class='keyword'>else</span><span> {   </span> </li><li><span>                    </span><span class='keyword'>throw</span><span> </span><span class='keyword'>new</span><span> Error(ERRORS['EventQueue.NO_SUCH_EVENT']+':'+event);   </span> </li><li class='alt'><span>                }                  </span> </li><li><span>            }   </span> </li><li class='alt'><span>        });   </span> </li><li><span>        </span><span class='keyword'>return</span><span> constructor;   </span> </li><li class='alt'><span>    })();   </span> </li><li><span>    </span><span class='comment'>/* </span>  </li><li class='alt'><span><span class='comment'>     * a class of message queue, used to invoke messages orderly </span> </span> </li><li><span><span class='comment'>     */</span><span>  </span></span> </li><li class='alt'><span>    jsLoader.MessageQueue=(</span><span class='keyword'>function</span><span>() {    </span> </li><li><span>        </span><span class='keyword'>var</span><span> constructor=</span><span class='keyword'>function</span><span>() {   </span> </li><li class='alt'><span>            </span><span class='keyword'>this</span><span>._queue=[];   </span> </li><li><span>            </span><span class='keyword'>this</span><span>._listened=</span><span class='keyword'>null</span><span>;   </span> </li><li class='alt'><span>        }   </span> </li><li><span>        Util.extend(constructor.prototype,{   </span> </li><li class='alt'><span>            </span><span class='comment'>/** </span>  </li><li><span><span class='comment'>             * 队列监听器,识别队列中是否有可以产生的消息 </span> </span> </li><li class='alt'><span><span class='comment'>             */</span><span>  </span></span> </li><li><span>            _listen:</span><span class='keyword'>function</span><span>() {   </span> </li><li class='alt'><span>                </span><span class='keyword'>var</span><span> _this=</span><span class='keyword'>this</span><span>;                </span> </li><li><span>                </span><span class='keyword'>if</span><span> (</span><span class='keyword'>this</span><span>._listened) {   </span> </li><li class='alt'><span>                    </span><span class='keyword'>if</span><span> (</span><span class='keyword'>this</span><span>._queue.length==0) {   </span> </li><li><span>                        setTimeout(</span><span class='keyword'>function</span><span>() {   </span> </li><li class='alt'><span>                            _this._listen()   </span> </li><li><span>                        },500);   </span> </li><li class='alt'><span>                    } </span><span class='keyword'>else</span><span> {   </span> </li><li><span>                        </span><span class='keyword'>this</span><span>.inform();   </span> </li><li class='alt'><span>                    }   </span> </li><li><span>                }   </span> </li><li class='alt'><span>            },   </span> </li><li><span>            </span><span class='comment'>/** </span>  </li><li class='alt'><span><span class='comment'>             * 启动监听器 </span> </span> </li><li><span><span class='comment'>             */</span><span>  </span></span> </li><li class='alt'><span>            startListen:</span><span class='keyword'>function</span><span>() {   </span> </li><li><span>                </span><span class='keyword'>this</span><span>._listened=</span><span class='keyword'>true</span><span>;   </span> </li><li class='alt'><span>                </span><span class='keyword'>this</span><span>._listen();    </span> </li><li><span>            },   </span> </li><li class='alt'><span>            </span><span class='comment'>/** </span>  </li><li><span><span class='comment'>             * 停止监听器 </span> </span> </li><li class='alt'><span><span class='comment'>             */</span><span>  </span></span> </li><li><span>            stopListen:</span><span class='keyword'>function</span><span>() {   </span> </li><li class='alt'><span>                </span><span class='keyword'>this</span><span>._listened=</span><span class='keyword'>false</span><span>;   </span> </li><li><span>            },   </span> </li><li class='alt'><span>            </span><span class='comment'>/** </span>  </li><li><span><span class='comment'>             * 通知消息队列,另起产生队列头部的一个消息 </span> </span> </li><li class='alt'><span><span class='comment'>             */</span><span>  </span></span> </li><li><span>            inform:</span><span class='keyword'>function</span><span>() {   </span> </li><li class='alt'><span>                </span><span class='keyword'>if</span><span> (</span><span class='keyword'>this</span><span>._queue.length==0) {   </span> </li><li><span>                    </span><span class='keyword'>this</span><span>._listen();   </span> </li><li class='alt'><span>                    </span><span class='keyword'>return</span><span>;   </span> </li><li><span>                } </span><span class='keyword'>else</span><span> {   </span> </li><li class='alt'><span>                    </span><span class='keyword'>var</span><span> message=</span><span class='keyword'>this</span><span>._queue.shift();   </span> </li><li><span>                    </span><span class='keyword'>var</span><span> scope=</span><span class='keyword'>this</span><span>._queue.shift();   </span> </li><li class='alt'><span>                    </span><span class='keyword'>var</span><span> args=</span><span class='keyword'>this</span><span>._queue.shift();   </span> </li><li><span>                    </span><span class='keyword'>try</span><span> {   </span> </li><li><br/></li></ol></div></div><div class='quote_div'>呵呵,原来在12月份就有这么个东西发布了呢,看样子不错,不过代码没仔细看。对于bingo我也很长时间没空去进一步完善了,希望来年来完善一下。冒味问下,你是与狼共舞?</div>
1 楼 sun2grit 2008-01-12  
能举几个简单的调用示例吗?

相关推荐

Global site tag (gtag.js) - Google Analytics