导言
Ext 封装了自己的事件机制,除了支持原始的鼠标和键盘事件之外,还能支持高级语义的事件,如 load 、 beforeLoad 、 render 、 destory 等等。
这一部分内容专门来解析 Ext 的事件机制,我打算用四种方法来解析这部分内容,力求稍有 js 基础的人都能看懂: 1 、源码注释翻译; 2 、执行流程图和源码片段截图; 3 、简单的 UML 类图; 4 、自定义测试代码。
这部分内容从最受大家关注的 Ext.onReady() 这个方法开始。 OK ,不要害怕,我会确保你能看懂的, Let’s go!
Ext.onReady()
大家经常会这么开始 Ext 的代码:
Ext.onReady(function(){
//……
})
这么做的目的是为了确保浏览器在文档加载完成之后再来执行我们的 js 。为了能更快更方便地理解 Ext.onReady() 这个方法到底做了什么,我们先来整理一下自己的思路。
书接上文,在“《仔仔细细分析 Ext 》 Ext 的事件模型之一 小沈阳的烦恼”一文中,我们自己制作了一段粗糙的代码来模拟这个过程,思路很简单:
第一步:先做一个简单的数组 var funcs=[] ,这个数组用来存放所有需要在文档一加载完成就开始执行的方法;
第二步:自己写一个叫 run() 的方法。这个方法只做一件事,它把第一步保存在 funcs 数据里面的函数全部拿出来依次执行一遍。
第三步:使用 js 原生的事件注册方式把第二步的 run() 方法注册到 window.onload 事件上。这样,一旦文档加载完成,这个方法就被执行。这样,我们预先放在 funcs 数组里面的方法就全部被执行了。
这段代码完整拿来看看:(原文请翻阅我的 blog:damoqiongqiu.iteye.com )
MyExt={ // 全局静态对象
version:'1.0',
isReady:false, // 文档是否加载完成标志
funcs:[], // 缓存函数的数组
onReady:function(f){
if(MyExt.isReady) f();
else MyExt.funcs.push(f);
},
run:function(){
if(MyExt.isReady) return;
for(var i=0;i<MyExt.funcs.length;i++){
try{// 为了避免一个方法的错误影响到其它方法,一定要有 try 和 catch
var f=MyExt.funcs[i];
f();
}catch(e){
alert(" 事件发生异常了 "+e);
}
}
MyExt.isReady=true;
funcs=[];// 清空一下
}
};
if(window.addEventListener){// 标准的 DOM2 事件注册
window.addEventListener("load",MyExt.run,false);
}else if(window.attachEvent){//IE 的事件注册
window.attachEvent("onload",MyExt.run);
}else {// 原始的 DOM0 的事件注册
window.onload=MyExt.run;
}
// 这样,我们就可以这么来写自己的代码,而不必关心文档加载的问题了。
MyExt.onReady(function(){
// 自己的代码
})
这段代码虽然简陋,但是核心的原理已经出来了:既然文档不加载完成我没办法干活,那好了,我不跟你纠缠,我先把要干的活都先存到一个筐子里面,等你(浏览器)觉得文档加载完了,可以干活了,你自己到这里来拿这些东西,一次性都给我干了吧!(貌似挺像批处理的撒!)
OK ,到这里应该没有什么难缠的地方吧?那么 OK ,恭喜你!因为不出意外的话,你肯定能很透彻地理解 Ext.onReady() 了!
Ext 采取的是类似的策略,只是实现的细节有所不同,下面我们来逐步深入地去解析。(下面的内容请不要跳着看。)
首先看一下 core 包下的 EventManage.js ,它里面有这么一句 :
很简单吧?原来 Ext.onReady 实际上执行的是 Ext.EventManager.onDocumentReady 这个方法。好,我们顺藤摸瓜,来看看 onDocumentReady 又是何方神圣。
(不知道为什么下面的段落老发不上来,转下一篇,sorry)
1 楼 awei0916 2010-01-13 14:08