对于 dojo 1.6 以前(包括1.6) 来说,这稍微有点麻烦。看源码:
真正执行初始化方法的是 dojo.loaded:
- 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.ready(addOnLoad) 加入的 function, 都保存在 dojo._loaders 的数组中。
- 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();
- }
- }
那么,只好重写 loaded 方法了:
我在 dojo 中加入了 _inits 数组,保存通过 addInit 注册的方法。然后检查所有通过 dojo.ready / addOnLoad 加入的方法,在dijit 完成注册(这时候 dojo parse 已经结束)后,把 _inits 里的方法插入。这样我就可以通过 dojo.addInit 在框架中加入一些处理,让它们始终在 dojo.ready / addOnLoad 加入的方法之前被执行。
- 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.ready(function() { console.log(1); });
- dojo.ready(function() { console.log(2); });
- dojo.addInit(function() { console.log('init'); });
- 日志: init
- 日志: 1
- 日志: 2
从 dojo 1.7 开始,dojo.js 就大部分重写了。 dojo.ready 的接口也变了:
加入了 priority 优先级参数,上面的实现可以大大简化。当默认通过 dojo.ready(function() {...}) 加入的方法,默认的 priority = 1000。
- var ready = dojo.ready = dojo.addOnLoad = function(priority,context,callback)
这样下面的代码就可以轻松搞定:
- dojo.addInit = function(obj) { dojo.ready(1,obj); };