日期:2014-05-16 浏览次数:20524 次
?????? 在ExtJs源码分析与学习—ExtJs事件机制(一)中分析了ExtJs对原生浏览器事件的封装。这篇进一步分析ExtJs对事件的封装和扩充。ExtJs会对浏览器本身的事件进行转换,是通过类Ext.EventObject来实现的,该类中通过自执行匿名函数返回Ext.EventObjectImpl对象,该对象用到了Ext.lib.Event(对原生浏览器事件的扩展)。
?
Ext.EventObject = function(){
var E = Ext.lib.Event,
…
Ext.EventObjectImpl = function(e){
if(e){
this.setEvent(e.browserEvent || e);
}
};
Ext.EventObjectImpl.prototype = {
…
};
return new Ext.EventObjectImpl();
}();
?
下面看Ext.EventObject中代码的实现
?
// safari keypress events for special keys return bad keycodes
safariKeys = {
3 : 13, // enter
63234 : 37, // left
63235 : 39, // right
63232 : 38, // up
63233 : 40, // down
63276 : 33, // page up
63277 : 34, // page down
63272 : 46, // delete
63273 : 36, // home
63275 : 35 // end
},
?该对象是为了兼容旧版本safari浏览器对部分键的按键事件返回值的处理,与其他浏览器的统一。
?
// normalize button clicks
btnMap = Ext.isIE ? {1:0,4:1,2:2} : {0:0,1:1,2:2};
?由于IE浏览器与其他浏览器的按键值(e.button)不同,所以定义该对象是为了实现所有浏览器的兼容。兼容后,0为左键,1为中键,2为右键。
接下来是类Ext.EventObjectImpl的定义
?
Ext.EventObjectImpl = function(e){
if(e){
this.setEvent(e.browserEvent || e);
}
};
?该类中对浏览器原生事件e进行了包装,调用了private method setEvent,setEvent是定义在Ext.EventObjectImpl.prototype下的
?
/** @private */
setEvent : function(e){
var me = this;
if(e == me || (e && e.browserEvent)){ // already wrapped
return e;
}
me.browserEvent = e;//把浏览器的原始事件保存到browserEvent中,可以作为是否包装的标识
if(e){
// normalize buttons
//该段代码处理了不同按键返回的e.button
me.button = e.button ? btnMap[e.button] : (e.which ? e.which - 1 : -1);//e.which原本是键盘事件
if(clickRe.test(e.type) && me.button == -1){
me.button = 0;
}
me.type = e.type;//事件名
//三个功能组合键
me.shiftKey = e.shiftKey;
// mac metaKey behaves like ctrlKey
me.ctrlKey = e.ctrlKey || e.metaKey || false;
me.altKey = e.altKey;
//键盘事件的keywode,and charcode
// in getKey these will be normalized for the mac
me.keyCode = e.keyCode;
me.charCode = e.charCode;
// cache the target for the delayed and or buffered events
//事件目标,E.getTarget(e)处理了不同浏览器的返回结果
me.target = E.getTarget(e);
// same for XY
me.xy = E.getXY(e);//Ext自定义的坐标属性
}else{//如果没有传入事件,则恢复属性为原始值
me.button = -1;
me.shiftKey = false;
me.ctrlKey = false;
me.altKey = false;
me.keyCode = 0;
me.charCode = 0;
me.target = null;
me.xy = [0, 0];
}
return me;
},
?该方法首先判断事件是否包装过,如已经包装了,则直接返回该包装的事件。
?me.browserEvent = e;//把浏览器的原始事件保存到browserEvent中
?me.button = e.button ? btnMap[e.button] : (e.which ? e.which - 1 : -1);//e.which原本是键盘事件
???? if(clickRe.test(e.type) && me.button == -1){
???????? me.button = 0;
?}
该段代码处理了不同按键返回不同的e.button
其他代码的功能,可参见代码注释
?
?
接着看stopEvent方法
?
stopEvent : function(){
var me = this;
if(me.browserEvent){
if(me.browserEvent.type == 'mousedown'){
Ext.EventManager.stoppedMouseDownEvent.fire(me);
}
E.stopEvent(me.browse