日期:2014-05-16 浏览次数:20435 次
?????? 在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