Ext.onReady 这个函数我想是最常用的函数了吧,毕竟没有 ready 前什么也不可以做的。
onReady的参数是一个函数 。 其实真正的调用是
Ext.onReady = Ext.EventManager.onDocumentReady;
而 Ext.EventManager 则是一个管理事件的对象,而且是单例的,为啥不做成静态呢,应该是为了不暴露里面的 private 函数喽,这也是对 传统语言private函数的一个实现 。
Ext.EventManager = funtion() { //private or privileged function xx(){ }; var pub ={ //可以调用xx }; //..... return pub; }();
而 onDocumentReady 则是将他的参数加入到一个自定义事件的 listener 列表中去了,关于自定义事件以及事件监听器如何排队,如何触发监听器暂时不分析了。可这个 event 怎么来的呢,正是在 onDocumentReady 初始的
onDocumentReady:function(f){ //页面加载好就直接触犯事件处理函数返回 //.. //页面没有加载好且自定义事件没有初始化,就初始化自定义事件 if(!docReadyEvent){ initDocReady(); } //自定义事件有了,把事件处理函数添加到自定义事件的 listeners 列表,等待事件触发后批处理 }
在初始这个事件过程中,终于看到了我们熟悉的 onload
var initDocReady = function(){ //自定义事件,建立监听器队列 docReadyEvent = new Ext.util.Event(); //gecko内核,和opera利用那个DOMContentLoaded事件 if(Ext.isGecko || Ext.isOpera) { document.addEventListener("DOMContentLoaded", fireDocReady, false); } //ie利用script的defer属性 else if(Ext.isIE){ document.write("<s"+'cript id="ie-deferred-loader" defer="defer" src="/'+'/:"></s'+"cript>"); var defer = document.getElementById("ie-deferred-loader"); defer.onreadystatechange = function(){ if(this.readyState == "complete"){ fireDocReady(); } }; } //safari没有办法?只能定时判断document,dom树的状态 else if(Ext.isSafari){ docReadyProcId = setInterval(function(){ var rs = document.readyState; if(rs == "complete") { fireDocReady(); } }, 10); } //最坏情况,新浏览器??load 比上述事件先触发?? //fireDocReady 会判断如果已经触发过一次就不再处理了。 // no matter what, make sure it fires on load E.on(window, "load", fireDocReady); };
这样的话就实现了多个操作附加到了ext ready上面. ( 09年再读:ie 利用script defer属性 ,firefox监控domready事件,dom树加载完毕比window load事件要早得多,image标签加载需要时间的 )
这样ext 屏蔽了浏览器差异 ,关键是ext使用了它的通用事件模型,从而整合到了一个统一的框架中 。