jquery-1.9.1源分析系列(十)事件系统的事件结构

jquery-1.9.1源分析系列(十)事件系统的事件结构
这也是一个重要的功能点。

分析在分析源代码有助于理解源代码的结构。事实上,在jQuery的到来,Dean Edwards的跨浏览器AddEvent()设计已经是优秀的,和jQuery事件系统的设计理念也正是基于这个想法,所以我们首先分析Dean Edwards的前辈事件绑定。

A. jQuery事件的原型——跨浏览器AddEvent(Dean Edwards设计)

源代码解释
事件添加方法
函数AddEvent(元素、类型处理){
确保每个不同的事件响应函数只有一个ID
如果(!汉德勒。$ GUID)处理。$ GUID = AddEvent GUID + +;
维护一个事件/元素属性,初始化为一个空对象。
/ / element.events结构类似于点击:{ {…},dbclick:{…},{ } }变化:…
如果(element.events!=元素(事件){ };
尝试删除相应的输入element.events当前对象/事件类型(这更像是一个对象数组),分配的句柄
如果对象不符合当前的事件/型element.events类型
var处理程序=元素。事件{类型};
如果(!处理){
处理程序=元素.事件{类型};
如果元素 / /有一个相应的事件响应的方法,例如,有一个onclick方法
onClick / /元素分配到处理器的0要素,处理结构:
{ / / 0:功能(e){…} },这就是为什么addevent.guid初始化为1,0的预留空间
对element.events结构: / / ,点击{:0:功能(e){ } },{ / *…省略其他事件类型
如果(元素 +类型}){
处理程序{ 0 } =元素++ };
}
}
存储处理器/处理器,处理器的当前事件。$ GUID = AddEvent。GUID + +;addevent.guid = 1;必须从1开始累积
因此,它是可能的,处理程序的结构是函数(e){ 0:},{…1:函数(2:){ },{ } }(函数)…
处理程序{;
/ /一个handleEvent定义(事件)的功能,这个功能将被绑定到事件,作为入口的元素类型的事件。
描述:点击 /元,将触发HandleEvent函数,会发现element.events handleEvent函数,调用相应的function.handleevent可以称为主要监控功能
元{ +型} = HandleEvent;
};
/计数器
addevent.guid = 1;
功能removeevent(元素、类型、处理){
从哈希表中删除事件处理程序
如果(element.events元。事件{型}){
删除元素{事件{ { };
}
};
功能HandleEvent(事件){
与ie兼容
事件=事件window.event | |;
/ /这是响应事件的节点,与事件的属性(添加AddEvent)在此连接
获取相应的事件响应函数列表
var处理程序=此事件{事件};
循环响应函数列表的实现
对于(在处理程序中的var i){
保持范围正确,即这个关键字
本。$ HandleEvent =处理{我};
这$ HandleEvent(事件);
}
};
重新排列数据结构并使用一个示例
函数F0(){…}
函数f1(){…}
函数F2(){…}
函数F3(){…}
VaR DOM = document.getelementbyid(蔡);
AddEvent(DOM,点击
AddEvent(DOM,变化
AddEvent(DOM,变化
AddEvent(DOM,点击
AddEvent(DOM,变化
后()函数AddEvent当前数据结构:
元:{
Onclick:HandleEvent(事件),的 / /单击事件的主要监控功能
onchage:HandleEvent(事件),主要监测功能的 / /更改事件
事件:{
单击:这是一个类数组。
0:F0,元素的现有事件
1:F1,下标1实际上是f1。
3:F3/3下标实际上是F3 $ GUID,请注意每个响应事件都有一个唯一的$ GUID作为下标。

},
更改:{这是一个类数组
1:F1,
2:F2,
3:F3
}
}
}
事件系统将标签$ GUID在每个响应函数,即在AddEvent第三参数处理程序(元素、类型、处理程序),在调用AddEvent秩序。源代码
确保每个不同的事件响应函数只有一个ID
如果(!汉德勒。$ GUID)处理。$ GUID = AddEvent GUID + +;
最后三个响应函数的$ GUID标签分别是

f1 $ $ = 1

F2 $ $ GUID = 2

3美元

并根据源代码

处理程序{;
然后一个函数是固定在任何事件响应函数的设置,例如,单击更改事件调用F3为响应事件,然后F3的下标位置element.events.click和element.events.change是F3。$ GUID = 3,即元。事件。单击{ 3 } =元。事件。改变{ 3 } = F3。

这个假设还添加了一个绑定事件:AddEvent(DOM,焦点,F3);元。事件。焦点{ 3 } = F3;这是物体的方便比较的数组,没有下标0,1,2直接在3阵是不可能的,但3的对象可以作为一个属性名称的对象。

实际上,这种设计具有jQuery事件系统的雏形,它包含了几个最重要的特性:

1)对元素的所有事件都会被存储在element.events属性而不是直接绑定到元素。这样的事件可以有许多响应函数。

2)HandleEvent是所有元素的事件的主要监控功能,和它管理的所有功能单元。

3)所有浏览器都支持元素++事件绑定,并在浏览器之间兼容。

嗯,理解的事件AddEvent结构,这种想法真让人觉得一双明亮的眼睛。下面分析jQuery事件结构

jQuery的事件结构

到jquery.event.add功能添加的所有功能。这个功能主要有两个功能:添加事件和附加很多事件的相关信息。我们直接进入源代码,源代码,和Dean Edwards的跨浏览器兼容性的加法处理类似事件。

源代码分析
问题补充:功能(元素、类型、处理程序、数据选择器){
VaR的TMP,事件,T,handleobjin,
特别的,eventhandle,handleobj,
处理程序、类型、命名空间、origtype,
/ /缓存数据获取相应的元素节点
ElemData = jQuery._data (elem);
//没有数据或文本/注释节点不能附加事件(但允许添加其他普通对象)
如果(!elemdata){
返回;
}
调用者可以通过处理程序来自定义数据。
如果(处理程序){
handleobjin =处理程序;
处理程序= handleobjin.handler;
选择= handleobjin.selector;
}
确保函数只具有处理程序 id/id,后续操作将用于查找/删除此处理程序函数。
如果(!汉德勒。GUID){
handler.guid = jQuery GUID + +;
}
如果它是第一个输入事件结构和主事件来初始化元素以响应入口
如果(!(= elemdata事件。事件)){
事件= elemdata.events = { };
}
如果(!(eventhandle = elemdata。手柄)){
eventhandle = elemdata.handle =功能(e){
当一个事件发生在该页面被卸载,放弃jquery.event.trigger(第二事件),
返回类型(E | | jQuery!= = core_strundefined!jquery.event.triggered!= e.type)
JQuery.event.dispatch.apply(eventhandle.elem,参数):
未定义;
};
/ /元素作为一种处理IE的特点功能以防止非本地内存泄漏引起的事故
eventhandle.elem =元;
}
处理由空间分隔的多个事件
/ /如jQuery(…)。Bind(鼠标悬停mouseout
/ / / core_rnotwhite = S + / G;匹配空白字符
类型=(类型| |)。比赛(core_rnotwhite)| |{ };
T = types.length;
当(t){
//rtypenamespace = / ^ (({^.}*): (1) / |.);
获取名称空间和原型事件
TMP = rtypenamespace.exec(类型{T})| | { };
类型= origtype = TMP { 1 };
命名空间=(TMP { 2 } | |)。分裂(。(排序);
如果事件/更改类型,则使用特殊事件处理程序处理更新的事件类型。
特殊= jQuery事件。特殊类型| | } { } {;
/ /如果选择器中定义的特殊API的事件类型,或给他一个类型
类型=(选择special.delegatetype特殊。bindtype)| |型;
输入一组新的特殊更新
特殊= jQuery事件。特殊类型| | } { } {;
/ / handleobj整个事件处理
handleobj = jquery.extend({
类型:类型,
OrigType:origtype,
数据:数据,
汉德勒:处理者,
handler.guid GUID,
选择器:选择器,
在库实现中使用。在'选择' POS匹配
needscontext :新/ regexp(^+空格+*+ ~ { } |:(甚至|奇|情商| GT | LT | n |第一|最后):((+
/ /空格+*((- D) d)+空格+* )|)(= { } ^ - |美元)
用于确定亲密关系
needscontext:选择jquery.expr.match.needscontext.test(选择器),
命名空间:namespaces.join(,)
},handleobjin);
第一次用于初始化事件/处理器队列时
如果(!(处理程序=事件{类型}){
处理程序=事件{ } };
handlers.delegatecount = 0;
/ /非自定义事件,如果特殊事件处理程序返回false,你只能使用addEventListener / attachevent
如果(special.setup | |!special.setup.call(元素、数据、命名空间、eventhandle)= false){
将元素绑定到全局事件
如果(元素。addEventListener){
elem.addeventlistener(类型,eventhandle,假);
} else if(元素。attachevent){
elem.attachevent(+型,eventhandle);
}
}
}
自定义事件
如果(特殊的。添加){
special.add.call(元素,handleobj);
如果(!handleobj。处理。GUID){
handleobj.handler.guid = handler.guid;
}
}
添加 / /事件对象handleobj处理列表元素的计数递增
如果(选择器){
Handlers.splice(处理程序。delegatecount + +,0,handleobj);
{人}
Handlers.push(handleobj);
}
事件跟踪被用于事件优化
jQuery;
}
防止内存泄漏
elem = null;
}
仍然用一个例子来说明jQuery的事件结构。

功能dohander(){ console.log(dohander )};
功能点(){ console.log(点);}
$(文档)。
在(单击)
在(单击)
在添加处理链接之后,事件被添加到元素中,并且相应的数据被添加到节点相应的缓存数据。
elemdata = jQuery _data(元素);
elemdata = { {
事件:{
单击:{数组{ 3 }
0:{
数据:未定义的{ }…},
GUID:2 id,处理函数
汉德勒:功能dohander(){…},
命名空间:
needscontext:假,
origtype:单击
选择:#中心 / /选择器是用来区分不同的事件源之间
键入:单击
}
1:{
数据:未定义的{ }…},
GUID:3,
汉德勒:函数点(){…},
命名空间:
needscontext:假,
origtype:单击
选择:#中心
键入:单击
}
2:{
数据:未定义,
GUID:3,
汉德勒:函数点(){…},
命名空间:
needscontext:假,
origtype:单击
选择器:未定义,
键入:单击
}
delegatecount:2,选择 / /委托事件的数量,这是主
长度:3
}
}
句柄:函数(e){…主入口*事件处理
元素:文件 / /属于对处理对象的特点
}
}
jQuery处理类似于Dean Edwards的跨浏览器兼容的事件处理,例如,将GUID添加到每个函数中;用事件对象存储事件响应对象列表,并具有总的事件处理入口句柄。

jQuery做了哪些改进

1)事件数据不再直接存储在节点,但采用的是jQuery的缓存系统(由内部缓存起来。_data访问)。

2)事件委托:绑定到当前节点(当前节点在实例文档的根节点)的功能不仅包含当前节点的触发事件(点击)治疗反应(例如选择器定义相应的事件处理函数的点);还代理其他节点(在这个例子#中心节点)触发事件(点击)对治疗的反应(事件处理事件的例子中选择#中心对应dohandler点);在后续分析委托机制。

3)增加了许多功能性数据,比如名称空间名称空间,主要用于定制事件触发,例如$(文档)。

这个jQuery的事件结构是清楚的,之后我们分析了事件的绑定和触发以及委托的原则。
免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。
相关文章
返回顶部