手机版

jQuery-1.9.1事件系统的源代码分析系列(X)事件封装

时间:2021-09-22 来源:互联网 编辑:宝哥软件园 浏览:

在上一篇文章中,我介绍了jQuery-1.9.1源代码分析系列(X)事件系统的事件架构。本文继续介绍jquery1.9.1源代码分析系列的相关知识。详情请见下文。

首先,应该理解的是,浏览器的本机事件是只读的,这限制了jQuery对它的操作。举一个简单的例子来理解为什么jQuery必须构造一个新的事件对象。

在委托过程中,当a被点击时,节点a委托节点b执行fn功能。当事件冒泡到节点B时,需要保证执行fn时上下文正确,节点A执行fn而不是节点B.如何保证执行fn的上下文是节点A:看源代码(红色部分)。

//执行ret=((jquery . event . special[handleobj . orig type]| | { })。handle | | handleobj.handler)。apply (matched.elem,args);使用apply将执行函数的上下文替换为节点a (matched.elem)。另一点是args[0]是事件对象事件。以及如何保证事件是节点a的事件?这是重要属性event.currentTarget的功能,所以在应用之前还有一步。

event . CurrentTarget=matched . elem;直接更改事件对象的currentTarget属性,这在浏览器本地事件中是做不到的。这就是为什么jQuery的事件对象是基于本地事件构造的。

事件有两种:鼠标事件和键盘事件(不知道什么时候可以添加触摸事件)。看看两者的详细属性。

其中一些是浏览器自己的,但不是W3C标准。JQuery将事件属性分为三个块。

属性jquery . event . prop :“alt键气泡可取消ctrl键当前目标事件阶段元键相关目标shift键目标时间戳视图哪个”。拆分(“”)。

特定于事件的属性jquery . event . key hooks . prop :“charchar code key key code”。拆分(“”)。

属性jquery . event . mouse hooks . prop :“从元素offsetx offsety pagex pagex screeny到元素的按钮clientx clienty”。拆分(“”)。

A.构造一个新的事件对象jquery . event . fix(original vent)。

构建新的事件对象分三步完成。

第一步是使用event=new jquery . event(originalEvent)构造一个新的事件对象(如果不理解new的功能,请点击此处),在创建事件时,添加isDefaultPrevented、originalEvent、type、TiMer的标记,事件已经更正(优化使用,避免不必要的处理)。jQuery的源代码。活动(src、道具)如下。

jQuery。Event=function(src,props ) { //不使用' new '关键字允许实例化if(!(这是jQuery的实例。事件){返回新的jQuery。活动(src、道具);} //src是事件对象if (src src.type) {this。originalevent=srcthis . type=src . type;//可能会标记有冒泡事件的文档,以防止发生默认事件;函数可以反映这个的正确值。is default prevented=(src . default prevented | | src .返回值===false | | src . getpreventdefault src . getpreventdefault())?returnTrue : returnFalse//src是事件类型} else { this.type=src}//将显式提供的功能添加到事件对象if (props) {jquery。延伸(这个,道具);}//如果有多个传入事件,则创建时间戳。this .时间戳=src src .时间戳| | jquery . now();//标记事件已被更正。这个[jquery . expando]=true;};在第一步中构造的事件对象。

第二步是区分当前事件是什么类型的事件,然后从浏览器本地事件originalEvent中逐个复制对应的属性。

//创建可写的事件对象副本,并格式化一些特征名称var i,prop,copy,type=event.type,originalEvent=event,fixHook=this。fix hooks[type];if(!修理钩子){这个。fix hook[type]=fix hook=//rmouseevent=/^(?鼠标|上下文菜单)|单击/rmousevent。测试(类型)?这个。鼠标挂钩: //rkeyevent=/^key/rkeyvent。测试(类型)?这个。key hooks : { };}//获得要从原生事件中拷贝过来的属性列表copy=fixHook.props?这个。道具。concat(FixHook。道具):这个。道具;//将原生的属性都拷贝到新的事件上I=copy . length while(I-){ prop=copy[I];事件[道具]=原始级别[道具];}第三步,相关属性的兼容处理

//IE9修正目标特征值if(!事件。target){ event。target=originalevent。srcelelement | | document} //Chrome 23,Safari?目标特征值不能是文本节点if(事件。目标。nodetype===3){事件。目标=事件。目标。父节点;} //IE9,对于鼠标/键盘事件,如果元密钥没有定义则设置metaKey==false event.metaKey=!event.metaKey//调用钩住的过滤器返回fixHook.filter?fixHook.filter(事件,原始级别):事件;最后那句代码针对鼠标事件和键盘事件做兼容适配处理。

fixHook.filter可能是jQuery.event.keyHooks.filter

keyHooks.filter:函数(事件,原始){ //给键盘事件添加哪个特征值if(事件。what==null){ event。什么=原创。charcode!=null?原创。charcode :原件。密钥代码;}返回事件;}或这jQuery.event.mouseHooks.filter

mouseHooks.filter:函数(事件,原始){ var body,eventDoc,Doc,button=original.button,from element=origin。从元素;//如果事件页面X/Y特征不见了,用可用的客户X/Y来计算出来if(事件。PageX==null原件。ClientX!=null){事件文档=事件。目标。ownerdocument | | document文档=事件文档。文档元素;body=eventDoc.bodyevent。pagex=原件。clientx(文档。阴囊|身体。scrolleft | | 0)-(doc。clientleft | | body。client left | | 0);事件。pagey=原创。客户(医生。医生。滚动顶部| |正文。滚动顶部| | 0)-(文档。clienttop | | body。client top | | 0);} //如果必要的话添加相关目标特征if(!事件。元素的相关目标){ event。相关目标=来自元素===事件。目标?原创。to ElEMENT : FrOm ElEMENT} //添加点击事件哪个特征值: 1===左;2===中间;3===右//备注:按钮不标准,因此不要是使用if(!事件。哪个按钮!==未定义){ event.which=(按钮1?1 :(按钮2?(按钮4?2 : 0 ) ) );}返回事件;}构建完成的最新事件对象如下(以鼠标事件为例)

原生的事件保存在了原始级别中,目标保存了目标节点(委托的节点、事件源),其他信息略过

b.重载事件方法

构建新的事件对象事件=新的jQuery .事件(原始级别)时,事件会继承jQuery.event.prototype中的方法。来看一看有哪些方法

前面分析了jQuery.event.prototype中重载了停止传播方法的作用:处了调用事件对象的阻止冒泡方法以外,还有一个作用就是被委托节点有多个被委托事件处理等待处理时,其中一个事件调用了event.stopPropagation()将阻止后续事件处理的执行。点击这里搜索关键字查看

preventDefault函数也是有类似的作用预防故障函数中增加了这段代码

这个。ispropagationtop=返回true在触发事件引发函数和模拟冒泡模仿函数中都会根据isPropagationStopped()判断是否要执行数字正射影像图节点的默认操作。源码如下

isImmediatePropagationStopped是停止传播特殊用法,isImmediatePropagationStopped会直接阻止掉当前的处理和后面等待执行的事件处理,而停止传播会执行完当前的处理,然后阻止后面等待执行的事件处理。

源码如下

//jQuery。事件基于数字正射影像图事件所指定的ECMAScript语言绑定//http://www . w . org/TR//WD-DOM-Level-事件-/ECMA-脚本-绑定。html jquery。事件。prototype={ is defaultprevented : return false,is propagationtop : return false,isimmediatepropationtop : return false,preventdefault3360 function(){ var e=this。origin事件;这个。isdefaultprevented=返回trueif(!e){ 0返回;} if(e . prevent default){ e . prevent default();//IE支持} else { e.returnValue=false}},stopperopagations : function(){ var e=this。原创;这个。ispropagationtop=返回trueif(!e){ 0返回;} if(e . stopperpagation){ e . stopperpagation();}//IE支持e.cancelBubble=true },stopImmediatePropagation:函数(){这个。isimmediatepragationstop=return true;这个。stopperpagation();}}以上就是本文给大家介绍的jQuery-1.9.1源码分析系列(十)事件系统之事件包装,希望大家喜欢。

版权声明:jQuery-1.9.1事件系统的源代码分析系列(X)事件封装是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。