博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
读Ext之八(原生事件对象的修复及扩充)
阅读量:6704 次
发布时间:2019-06-25

本文共 5011 字,大约阅读时间需要 16 分钟。

Ext库也对浏览器原生的事件对象做了包装,以保证兼容所有浏览器。 列举了浏览器原生事件对象各浏览器中兼容性, 列出了各种情况下事件对象的获取。

在Ext事件管理类 Ext.EventManager 中会悄悄的将浏览器原始事件对象进行转换

e = Ext.EventObject.setEvent(e);

Ext.EventObject 即为包装后的事件对象(暂称为Ext事件对象)。先从全局上看看该对象的实现,其中...省略了部分代码。

Ext.EventObject = function(){    var E = Ext.lib.Event,		...;    Ext.EventObjectImpl = function(e){        if(e){            this.setEvent(e.browserEvent || e);        }    };    Ext.EventObjectImpl.prototype = {           /** @private */        setEvent : function(e){            var me = this;			...        },		...     };    return new Ext.EventObjectImpl();}();

 

可看到匿名函数执行后返回了Ext.EventObjectImpl的实例对象,该对象才是真正的Ext.EventObject。

这一点和jQuery类似,jQuery中是new了一个Event类。
第一句

var E = Ext.lib.Event,

变量E暂存了Ext.lib.Event对象,该对象在 中已经介绍了。后面的很多方法都要用 E 来实现。

第二个变量 safariKeys 为一个对象,

// safari keypress events for special keys return bad keycodessafariKeys = {    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中keypress事件返回错误的键码。但我用Safari 5.0.3测试input,document.body 。

回车键(enter)返回的是13,正确的。方向键(left等)和翻页键(page up等)则不会触发。
测试代码如下

var inp = document.getElementById('txt');	inp.onkeypress = function(e){	e = window.event || e;	alert(e.keyCode);}document.body.onkeypress = function(e){	e = window.event || e;	alert(e.keyCode);}

之前已经提到过要获取按键值应该使用keydown或keyup事件。这里应该是为了兼容旧版本的Safari。

第三个变量是btnMap

// normalize button clicksbtnMap = Ext.isIE ? {1:0,4:1,2:2} :        (Ext.isWebKit ? {1:0,2:1,3:2} : {0:0,1:1,2:2});

用来统一鼠标按键值。 有详细分析,不重复了。经测试,webkit内核的Safari5和Chrome7在mousedown/mouseup事件中左,中,右键返回的是符合标准的0,1,2。因此这里对webkit的判断是可去掉的。

 

接下来是 Ext.EventObjectImpl 类的定义

Ext.EventObjectImpl = function(e){    if(e){        this.setEvent(e.browserEvent || e);    }};

 

如果传了浏览器原生事件对象,则调用this.setEvent,this.setEvent是挂在Ext.EventObjectImpl的原型上的。原型上还有很多其它方法,逐个看

setEvent : function(e){    var me = this;    if(e == me || (e && e.browserEvent)){ // already wrapped        return e;    }    me.browserEvent = e;    if(e){        // normalize buttons        me.button = e.button ? btnMap[e.button] : (e.which ? e.which - 1 : -1);        if(e.type == 'click' && 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;        // 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        me.target = E.getTarget(e);        // same for XY        me.xy = E.getXY(e);    }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;},

 

var me = this;

将this暂存到me上。接着判断所传的是否就是本身,如果是则不再包装直接返回。仅当是浏览器原生事件对象才进行包装。

 

me.browserEvent = e;

把浏览器原始事件对象挂在this上,即该类的字段browserEvent就是浏览器原始对象。因为有时会用到浏览器原始对象。

me.button = e.button ? btnMap[e.button] : (e.which ? e.which - 1 : -1);

先从btnMap中取,上面已经提到了。e.which原本是键盘事件,jQuery中将鼠标按键也存在e.which中,Ext这里是为了兼容jQuery。

if(e.type == 'click' && me.button == -1){    me.button = 0;}

建议获取判断鼠标按下哪个键应该使用mousedown/mouseup事件,这里是为了兼容click事件。但有点问题,IE6/7/8中左键单击(click)事件为0,但中键和右键单击(click)则无法触发该事件。这里的实现欠妥。

 

me.type = e.type; me.shiftKey = e.shiftKey;

事件类型(如click)和shiftKey复制到this上。

接着是ctrlKey,altKey,keyCode,charCode。
接着是target,使用E.getTarget(e)获取。E.getTarget在第四篇提到了。
接着是xy,xy不是事件对象原有的属性。而是Ext自定义的。

 

setEvent说了,看stopEvent

stopEvent : function(){    var me = this;    if(me.browserEvent){        if(me.browserEvent.type == 'mousedown'){            Ext.EventManager.stoppedMouseDownEvent.fire(me);        }        E.stopEvent(me.browserEvent);    }},

用来停止事件冒泡,阻止元素默认行为。

有两点,其一对mousedown事件做了特殊处理Ext.EventManager.stoppedMouseDownEvent 实际是Ext.util.Event类的一个实例对象。如

pub.stoppedMouseDownEvent = new Ext.util.Event();

 

后续有一篇会读到该类。

其二,调用了E.stopEvent(me.browserEvent),这里的E即为Ext.lib.Event对象,第四篇提到了。接着是preventDefault,stopPropagation等

preventDefault : function(){    if(this.browserEvent){        E.preventDefault(this.browserEvent);    }},stopPropagation : function(){    var me = this;    if(me.browserEvent){        if(me.browserEvent.type == 'mousedown'){            Ext.EventManager.stoppedMouseDownEvent.fire(me);        }        E.stopPropagation(me.browserEvent);    }},

可看到都是调用E(Ext.lib.Event)来实现的,不再重复。

getTarget 采用事件代理时会用到,实现上用到了Ext.fly等,后续提到。getWheelDelta 用来获取滚轮的速度

getWheelDelta : function(){    var e = this.browserEvent;    var delta = 0;    if(e.wheelDelta){ /* IE/Opera. */        delta = e.wheelDelta/120;    }else if(e.detail){ /* Mozilla case. */        delta = -e.detail/3;    }    return delta;},

 

IE/Safari/Chrome/Opera中使用事件对象的wheelDelta属性,Firefox则使用detail属性。

属性的方向值也不一样,IE向前滚 > 0为120,相反在-120,Firefox向后滚 > 0为3,相反则-3。
好了,整个Ext事件对象读完了。可以看到Ext为了保证兼容,统一对原生事件对象做了修复,扩充等。

 

 

转载地址:http://ykblo.baihongyu.com/

你可能感兴趣的文章
Apache HBase的现状和发展
查看>>
反模式的经典 - Mockito设计解析
查看>>
Zip Slip目录遍历漏洞已影响多个Java项目
查看>>
独家揭秘:微博深度学习平台如何支撑4亿用户愉快吃瓜?
查看>>
Visual Studio 15.7预览版4改进Git、C++支持
查看>>
全新云服务:亚马逊AWS发布AWS Ground Station\n
查看>>
微软宣布支持基于虚拟机的Azure IOT Edge服务
查看>>
来自社区的Visual Studio Code使用体验和教程
查看>>
高效运维最佳实践:如何做好On-call和事故响应?
查看>>
TypeScript 3.3发布:改进了联合类型调用和构建时间
查看>>
利用Scikit-Learn和Spark预测Airbnb的listing价格
查看>>
数据建模NoSQL数据库的概念和对象建模符号
查看>>
微软宣布Azure Function支持Python
查看>>
3·15曝光丨智能机器人一年拨打40亿个骚扰电话,6亿人信息已遭泄露!
查看>>
ArchSummit深圳2016大会7折售票最后一周
查看>>
2019年React学习路线图
查看>>
Google Docs API正式可用,可自动化文档任务和内容管理
查看>>
清华\u0026商汤开源超高精度边缘感知人脸对齐算法
查看>>
全面了解大数据“三驾马车”的开源实现
查看>>
GitHub宣布推出Electron 1.0和Devtron,并将提供无限制的私有代码库
查看>>