论坛首页 Web前端技术论坛

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

浏览 5352 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-12-18  

首先很感谢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 {   
   发表时间:2008-01-12  
能举几个简单的调用示例吗?
0 请登录后投票
   发表时间:2008-01-12  
ajaxgo 写道

首先很感谢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 {   

呵呵,原来在12月份就有这么个东西发布了呢,看样子不错,不过代码没仔细看。对于bingo我也很长时间没空去进一步完善了,希望来年来完善一下。冒味问下,你是与狼共舞?
0 请登录后投票
   发表时间:2008-01-14  
sun2grit 写道
能举几个简单的调用示例吗?


下载的代码里面有示例
0 请登录后投票
   发表时间:2008-01-14  
brull 写道
呵呵,原来在12月份就有这么个东西发布了呢,看样子不错,不过代码没仔细看。对于bingo我也很长时间没空去进一步完善了,希望来年来完善一下。冒味问下,你是与狼共舞?

 

我不是与狼共舞哦,呵呵,不好意思

0 请登录后投票
   发表时间:2008-01-14  
ajaxgo 写道
brull 写道
呵呵,原来在12月份就有这么个东西发布了呢,看样子不错,不过代码没仔细看。对于bingo我也很长时间没空去进一步完善了,希望来年来完善一下。冒味问下,你是与狼共舞?

 

我不是与狼共舞哦,呵呵,不好意思


那看来对这个东西感兴趣的人还是有一些的,我也感到比较欣慰,再接再厉
0 请登录后投票
   发表时间:2008-04-21  
有的ext desktop就有一个js加载顺序的问题.

希望能用你的js loader解决
0 请登录后投票
   发表时间:2008-04-21  
我用了之后是可以按自己想的顺序加载了..

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

加上..我在js 的有调用的..一个也不要用.
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics