在ext-all.js文件可以找到Ext.onReady的定义:
Ext.onReady = function(fn, scope, options) {
Loader.onReady(fn, scope, true, options);
};
在这里调用了Loader对象的onReady方法,
onReady: function(fn, scope, withDomReady, options) {
var oldFn;
if (withDomReady !== false && Ext.onDocumentReady) {
oldFn = fn;
fn = function() {
Ext.onDocumentReady(oldFn, scope, options);
};
}
if (!Loader.isLoading) {
fn.call(scope);
}
else {
readyListeners.push({
fn: fn,
scope: scope,
priority: (options && options.priority) || 0
});
}
},
在上面的代码中,因为调用时withDomReady为true,所以只需判断Ext.onDocumentReady是否存在,如果存在,就建立一个匿名函数fn,准备执行Ext.onDocumentReady方法。最后是调用函数fn,执行Ext.onDocumentReady。
在EventManger.js中可找到Ext.onDocumentReady的定义:
onDocumentReady: function(fn, scope, options) {
options = options || {};
// force single, only ever fire it once
options.single = true;
readyEvent.addListener(fn, scope, options);
// If we're in the middle of firing, or we have a deferred timer
// pending, drop out since the event will be fired later
if (!(EventManager.isFiring || EventManager.hasDocReadyTimer)) {
if (Ext.isReady) {
EventManager.fireReadyEvent();
} else {
EventManager.bindReadyEvent();
}
}
},
在上面的代码中,readyEvent是Ext.util.Event的实例,options.single的作用是规定ready-Event事件只执行一次。接着将函数添加到Event实例内的监听事件列表中,最后判断DOM模型是否已加载完成。如果已加载完成,则调用fire方法依次执行监听事件列表中的函数。这样做的目的是:当存在多个onReady方法时,能保证所有的函数都能执行。如果还没有加载完成,而document对象的readyState属性为“complete”,表示文档其实已经加载完成了,但是没有设置isReady属性为true,那么可调用fireDocReady方法,其代码如下:
fireReadyEvent: function() {
// Unset the timer flag here since other onReady events may be
// added during the fire() call and we don't want to block them
EventManager.hasDocReadyTimer = false;
EventManager.isFiring = true;
// Ready events are all single: true, if we get to the end
// & there are more listeners, it means they were added
// inside some other ready event
while (readyEvent.listeners.length && !EventManager.isReadyPaused()) {
readyEvent.fire();
}
EventManager.isFiring = false;
EventManager.hasFiredReady = true;
Ext.EventManager.idleEvent.fire();
},
在上面的代码中,如果isReady不是true,则将其设置为true,然后移除文档的监听事件。首先调用Ext.supports的init方法检测当前运行环境的信息;然后调用onWindowUnload方法为文档绑定unload事件,触发后会删除页面的所有元素;最后再调用readyEvent的fire方法,开始执行我们定义的代码。
如果文档还没有加载完成,则执行bindReadyEvent方法,其代码如下:
bindReadyEvent: function() {
if (EventManager.hasBoundOnReady) {
return;
}
// Test scenario where Core is dynamically loaded AFTER window.load
if ( doc.readyState == 'complete' ) { // Firefox4+ got support for this state, others already do.
EventManager.onReadyEvent({
type: doc.readyState || 'body'
});
} else {
doc.addEventListener('DOMContentLoaded', EventManager.onReadyEvent, false);
win.addEventListener('load', EventManager.onReadyEvent, false);
EventManager.hasBoundOnReady = true;
}
},
看懂以上代码就应该很清楚整个执行过程了。在代码中,如果没有在页面中绑定监听事件,则绑定事件,非IE浏览器是绑定“DOMContentLoaded”事件,IE是绑定onload事件。对于旧版本的IE,会调用checkReadyState方法检查页面是否准备好,因为旧版本IE只能使用替代办法检查DOMContentLoaded事件。事件触发后执行fireDocReady方法。