dojo.ready(dojo.addOnLoad) “前传”


【dojo】dojo.ready(dojo.addOnLoad) “前传”
最近的项目中使用了dojo框架,每个页面中大量使用了 dojo.ready 来完成页面初始化的工作。但因为某种原因,需要在所有的 dojo.ready 之前做一些事。
对于 dojo 1.6 以前(包括1.6) 来说,这稍微有点麻烦。看源码:
[csharp] view plaincopy

    dojo.ready = dojo.addOnLoad = function(/*Object*/obj, /*String|Function?*/functionName){ 
            d._onto(d._loaders, obj, functionName); 
     
            if(d._postLoad && d._inFlightCount == 0 && !d._loadNotifying){ 
                d._callLoaded(); 
            } 
        } 

真正执行初始化方法的是 dojo.loaded:
[csharp] view plaincopy

    dojo.loaded = function(){ 
     
        d._loadNotifying = true; 
        d._postLoad = true; 
        var mll = d._loaders; 
     
        //Clear listeners so new ones can be added 
        //For other xdomain package loads after the initial load. 
        d._loaders = []; 
     
        for(var x = 0; x < mll.length; x++){ 
            mll[x](); 
        } 
     
        d._loadNotifying = false; 
         
        if(d._postLoad && d._inFlightCount == 0 && mll.length){ 
            d._callLoaded(); 
        } 
    } 

通过 dojo.ready(addOnLoad) 加入的 function, 都保存在 dojo._loaders 的数组中。
那么,只好重写 loaded 方法了:
[csharp] view plaincopy

    dojo._inits = []; 
    dojo.addInit = function(obj) { 
       dojo._inits.push(obj); 
    }; 
     
    dojo.loaded = function(){ 
        var d = dojo; 
        d._loadNotifying = true; 
        d._postLoad = true; 
     
        var mll = []; 
        for(var i=0; i<d._loaders.length; i++) { 
            console.log(d._loaders[i]); 
            mll.push(d._loaders[i]); 
            if (d._loaders[i].toString().indexOf('registerWin') > -1) 
                for(var j=0; j<d._inits.length; j++) 
                    mll.push(d._inits[j]); 
            } 
        } 
     
        d._loaders = []; 
        d._inits = []; 
     
        for(var x = 0; x < mll.length; x++){ 
            mll[x](); 
        } 
     
        d._loadNotifying = false; 
        if(d._postLoad && d._inFlightCount == 0 && mll.length){ 
            d._callLoaded(); 
        } 
    } 

我在 dojo 中加入了 _inits 数组,保存通过 addInit 注册的方法。然后检查所有通过 dojo.ready /  addOnLoad 加入的方法,在dijit 完成注册(这时候 dojo parse 已经结束)后,把 _inits 里的方法插入。这样我就可以通过 dojo.addInit 在框架中加入一些处理,让它们始终在 dojo.ready / addOnLoad 加入的方法之前被执行。

测试:
[javascript] view plaincopy

    dojo.ready(function() { console.log(1); }); 
    dojo.ready(function() { console.log(2); }); 
    dojo.addInit(function() { console.log('init'); }); 

结果:
[html] view plaincopy

    日志: init 
    日志: 1 
    日志: 2 


从 dojo 1.7 开始,dojo.js 就大部分重写了。 dojo.ready 的接口也变了:
[csharp] view plaincopy

    var ready = dojo.ready = dojo.addOnLoad = function(priority, context, callback) 

加入了 priority 优先级参数,上面的实现可以大大简化。当默认通过 dojo.ready(function() {...}) 加入的方法,默认的 priority = 1000。
这样下面的代码就可以轻松搞定:
[csharp] view plaincopy

    dojo.addInit = function(obj) { dojo.ready(1, obj); }; 


你可能感兴趣的:(JavaScript,dojo)