jQuery1.9.1源分析系列(十)事件系统绑定事件
让我们展示一下jQuery绑定事件是什么。
复制代码代码如下所示:
JQuery.fn.eventType({ {资料} },FN)
例如,事件类型是指事件类型,如点击:$(#蔡)。Click(FN);
数据这个参数通常不会用。这样的事件是必然的(#蔡),不代表事件,接近JS原生事件绑定。让我们在源代码看看
jquery.each(模糊焦点聚集focusout负荷调整滚动卸载单击双击+
MouseDown mouseup MouseMove mouseover mouseout MouseEnter MouseLeave +
改变选择提交KEYDOWN按键keyup错误中)。分裂(),功能(我的名字){
15事件 / /统一jquery.fn,叫this.on / this.trigger
函数(数据,FN){
返回arguments.length > 0
This.on(名字,null,数据,FN):
如果没有参数立即触发指定的事件
This.trigger(人名);
};
});
JQuery.fn.bind(类型数据},{,FN)
例如,$(#蔡)。Bind(单击事件直接绑定到$(#蔡)没有委托事件。源代码
函数(类型,数据,FN){
返回this.on(类型、空数据,FN);
},
Unbind:功能(类型,FN){
返回this.off(类型、空,FN);
}
jquery.fn.delegate(选择器、数据类型{,},FN)
顾名思义,委托函数用于委派事件,选择器的相应响应处理被委托给当前jQuery的匹配元素。
例如,$(document)。代表(#大、单击
当#大元素被点击,点击气泡事件到文档节点。
文档绑定处理事件,并且该处理事件被调用到事件分发服务器分派;
对应事件类型单击的所有委派事件列表处理程序都从调度中取出;
根据事件源event.target,在处理每个元素的选择器属性过滤掉,并在每个元素对应的节点事件源和代理节点之间的文件,包括事件源,并保存为handlerqueue。
在handlerqueue执行事件处理。
以上是一个一般流程,然后进行详细的分析。
委托:函数(选择器,类型,数据,FN){
返回this.on(类型、选择器、数据,FN);
},
undelegate:功能(选择类型,FN){
(名称空间)或(选择器、类型、FN })
返回arguments.length this.off(选择器= 1,**):this.off(类型,选择| | **,FN);
}
JQuery.fn.one(类型选择器{,} {,}数据,FN)
由一个()函数绑定的事件处理函数都是一次性的,事件处理函数只在第一次触发事件时执行,触发器之后将删除当前事件绑定。
例如,$(#蔡),(单击
$(文档)一个(单击源代码)
功能:(类型、选择器、数据、FN){
返回this.on(类型、选择器、数据,FN,1);
}
JQuery.fn.trigger(数据类型{,})
JQuery.fn.triggerHandler(数据类型{,})
触发触发器,每个元件匹配的jQuery对象对应类型的事件。例如,$(#蔡)。Trigger(点击);
TriggeHandler只是触发相应在jQuery对象匹配的元素的第一个元素类型的事件,并不会触发事件的默认行为。
指定类型立即触发事件jQuery对象中的所有元素
触发器:函数(类型,数据){
返回this.each(函数(){()
JQuery.event.trigger(类型、数据、本);
});
},
指定类型立即触发事件jQuery对象中的第一个元素,并且不会触发事件(如默认行为表单提交)
TriggerHandler:功能(类型、数据){
var elem =这{ 0 };
如果(元){
返回jquery.event.trigger(类型、数据元素,真的);
}
}
上面分析了这些事件绑定中的一些。有没有发现他们被束缚着这就是为什么我们提倡统一使用绑定(除了一个)。
JQuery.fn.on(类型选择器{,} {,}数据,FN)
上的事件绑定一半的代码是真正的处理不同的加工参数,这是价格的jQuery,标语写的少,做的更多,jquery.event.add绑定事件的最终用途。
在jquery.event.add绑定事件的几个关键点:
首先,使用内部缓存保存节点元素的事件信息
获取缓存数据
elemdata = jQuery _data(元素);
…
U3000 U3000 U3000 U3000 U3000 U3000 U3000
设置缓存数据
如果(!(= elemdata事件。事件)){
事件= elemdata.events = { };
}
如果(!(eventhandle = elemdata。手柄)){
eventhandle = elemdata.handle =功能(e){
…
};
/ /元素作为一种处理IE的特点功能以防止非本地内存泄漏引起的事故
eventhandle.elem =元;
}
第二,设置绑定事件信息,特别是指定的选择器选择器、响应处理处理程序、响应事件类型、命名空间名称空间。
/ / 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);
第三、真正代表事件列表放在节点的事件列表的前面,与delegatecount属性,这是同步的,events.click.length假设3和events.click.delegatecount假设2。然后该事件指定的事件。单击{ 0 }和事件。单击{ 1 }是一个委托事件。第三事件。{ 2 }对应的事件并不代表事件,但事件的节点。
添加 / /事件对象handleobj处理列表的元素,委托事件在前,委托代理计数递增
如果(选择器){
Handlers.splice(处理程序。delegatecount + +,0,handleobj);
{人}
Handlers.push(handleobj);
}
对源代码的结构和事件的添加进行了分析。请点击查看详情。
结合有一个共同的功能jquery.fn.on.there也是一种常见的功能jquery.fn.off为解开
JQuery.fn.off({类型选择器} { {,} },FN)
在传记中有一个特殊情况:当浏览器事件对象类型的事件,这意味着除去(解)event.selector指定代表事件。
传递的参数是和绑定处理函数。
如果(类型types.preventdefault类型。handleobj){
(事件)发出的
handleobj = types.handleobj;
/ / types.delegatetarget是事件的托管对象
jQuery(类型。delegatetarget)。关(
组合jQuery识别类型
handleobj.namespace handleobj.origtype + ,+ handleobj.namespace:handleobj.origtype,
HandleObj.selector,
handleobj.handler
);
返回此;
}
在任何情况下,调用函数的jquery.event.remove绑定事件。
对jquery.fn.off完整源代码如下
关闭:函数(类型,选择器,Fn){
无功handleobj,型;
传递的参数是和绑定处理函数。
如果(类型types.preventdefault类型。handleobj){
(事件)发出的
handleobj = types.handleobj;
/ / types.delegatetarget是事件的托管对象
jQuery(类型。delegatetarget)。关(
组合jQuery识别类型
handleobj.namespace handleobj.origtype + ,+ handleobj.namespace:handleobj.origtype,
HandleObj.selector,
handleobj.handler
);
返回此;
}
如果(typeof类型=对象){
(类型对象、选择器})
对于(类型输入){
This.off(类型选择器类型{型));
}
返回此;
}
如果(选择错误类型的选择| | = = = = = =功能){
({类型)
选择器;
选择器=未定义;
}
如果(Fn =假){
FN = returnfalse;
}
返回this.each(函数(){()
JQuery.event.remove(这类型,FN,选择器);
});
}
其次,分析底层API jquery.event.remove是联系在一起的事件。
jquery.event.remove
使用了基于函数调用的函数(jQuery)伤口是这个函数jquery.event.remove.the绑定的事件处理流程如下
1、我们分解要删除的事件类型和遍历类型。如果我们想删除没有事件名称的事件,只有名称空间意味着删除该命名空间下的所有绑定事件。
/ /分解的类型作为type.namespace数组元素作为一个单元
类型=(类型| |)。比赛(core_rnotwhite)| |{ };
T = types.length;
当(t){
TMP = rtypenamespace.exec(类型{T})| | { };
类型= origtype = TMP { 1 };
命名空间=(TMP { 2 } | |)。分裂(。(排序);
在所有事件中的当前元素的名称空间到解决方案(类型{)
如果(!型){
对于(在事件中键入){
JQuery.event.remove(元素、类型+类型{T},处理程序,选择,真的);
}
继续;
}
…
2。遍历类型过程,删除匹配事件,代理计数校正
类型=(选择special.delegatetype特殊。bindtype)| |型;
事件处理程序= {型| | } { };
TMP = TMP { 2 }(new RegExp(^ | 。)+ namespaces.join(。(:* 。|))+(。|美元));
删除匹配事件
origcount = = handlers.length;
当(j){
handleobj = { }处理{J}.;
为了满足各种条件,删除事件将被删除。
如果(mappedtypes | |(origtype = handleobj。origtype)
(| |!处理handler.guid = handleobj GUID)。
(| |!TMP tmp.test(handleobj。命名空间))
(选择器选择器handleobj.selector | | | |!= = = = = =**handleobj选择器。选择器)){
handlers.splice(J,1);
如果(handleobj。选择器){
handlers.delegatecount--;
}
如果(特殊。删除){
special.remove.call(元素,handleobj);
}
}
}
三.如果节点上指定类型的事件处理器已经空了,则移除事件上的事件处理对象。
删除事件处理对象
(无限递归,有可能避免在下一章的过程中删除特殊事件,这将具体说明这一情况)
如果(origcount!处理程序。长度){
例如,js_obj =无功 / / document.createelement(div);js_obj.onclick(=功能){…}
/ /以上js_obj是参考一个DOM元素和DOM元素在很长一段时间
如果(special.teardown | |!special.teardown.call(元素、命名空间、elemdata。手柄)= false){
JQuery.removeEvent(元素、类型、elemdata处理。);
}
删除事件{类型};
}
4。如果节点上没有绑定事件,则清空事件处理入口句柄。
如果(jquery.isemptyobject(事件)){
删除elemdata.handle;
/ /在元素上移除存放的数据并检查是否事件对象是空的,所以用它来代替删除
jQuery。_removedata(元素,事件);
}
延伸:浏览器事件删除jquery.removeevent
jquery.removeevent = document.removeeventlistener
功能(元素、类型、处理){
如果(元素。removeEventListener){
elem.removeeventlistener(类型、处理,假);
}
}:
功能(元素、类型、处理){
var+类型;
如果(元素。detachevent){
/ / # 8545,# 7054,避免在IE6-8内存泄漏的自定义事件
/ / detachevent需要传递的第一个参数是不确定
如果(typeof元素{,} = = = core_strundefined名字){
{姓名} = null元素;
}
elem.detachevent(名称、处理);
}
};
以上内容是一个小系列的jQuery 1.9.1源分析系列(十)事件系统绑定的事件,我希望你喜欢。