JavaScript 事件处理函数间 Event 对象全等性分析

作者:木棉

时间:2026-10-25

浏览:160

本文探讨同一元素绑定多个事件处理函数时,传入各函数的Event对象是否全等。分析表明,jQuery中通过liveHandler机制确保全等;原生addEventListener在Firefox等非IE浏览器中全等,而IE的attachEvent在冒泡事件中,通过window.event获取的对象与参数传递的对象不一致。

文章目录

此前曾遇到此类问题,但未进行总结。


如今再次遇到,为获取准确结论,特记录如下:


问题定义与jQuery实现机制

核心问题:同一事件绑定多个处理函数时,各函数接收的Event对象是否完全相等?



具体场景示例:


相关代码片段如下:

 
dom.addEvent('click',fna);
dom.addEvent('click',fnb);

问题1:若在fna中对Event对象添加属性,后续执行的fnb能否访问该属性?


问题2:执行fna和fnb时传入的Event对象是否全等,即 Eventfna === Eventfnb 是否成立?



标准文档篇幅较长,未仔细查阅其中关于此规则的具体说明,此处暂略。



对于jQuery,同一事件绑定的多个处理函数接收的Event对象是全等的。


在jQuery live绑定事件的实现中,针对可能被重复执行的liveHandler,通过额外给Event对象添加liveFired属性,使得在第一次执行后的liveHandler开始即退出:


相关判断逻辑如下:

 
if (event.liveFired === this || ...) {
return;
} 
///.... 
event.liveFired = this;

测试验证:


测试代码如下:

 
function a(e) {
e.abc = function() {
alert(a);
}; 
prevEvent = e;
prevIeEvent=window.event;
} 
function b(e,event) {
e.abc(); //fn
alert(e === prevEvent); //true
if(event=window.event){
alert(event===e); //false
alert(event===prevIeEvent);//false
alert(event===prevEvent);//false
} 
} 
var t = document.getElementById("p");
if (t.addEventListener) {
t.addEventListener('click', a, false);
t.addEventListener('click', b, false)
} else {
t.attachEvent('onclick', b);
t.attachEvent('onclick', a)
} 

原生绑定与IE浏览器差异分析

对于原生绑定事件方式[addEventListener,attachEvent],同一节点上多个处理函数间通过参数传递的Event对象是全等的。但在IE浏览器中,通过window.event形式获取的Event对象与参数传递的对象不全等,且不同处理函数间通过window.event获取的对象也不全等。


冒泡事件中的对象全等性验证

针对冒泡事件的情况:


相关代码示例:

 
dom.addEvent('click',fna);
domParentNode.addEvent('click',fnb);

在jQuery中,通过trigger触发事件时,冒泡事件各处理函数间的Event对象是全等的。但由用户实际行为触发的事件,则不是同一对象,自定义属性也无法传递,对取值和设置的修改不影响真正的originalEvent。


采用原生绑定事件方式[addEventListener,attachEvent]的情况:


测试代码如下:

 
function a(e) {
e.abc = function() {
alert(a);
}; 
prevEvent = e;
prevIeEvent=window.event;
} 
function b(e,event) {
alert(e.abc); //fn
alert(e === prevEvent); //true
if(event=window.event){
alert(event===e); //false
alert(event===prevIeEvent);//false
alert(event===prevEvent);//false
} 
} 
var t = document.getElementById("p");
if (t.addEventListener) {
t.addEventListener('click', a, false);
document.body.addEventListener('click', b, false);
} else {
t.attachEvent('onclick', a);
document.body.attachEvent('onclick', b);
} 

结果显示,在IE中使用attachEvent绑定冒泡事件时,各处理函数内的Event对象不一致。而在Firefox等浏览器中,使用addEventListener则保持对象全等。


事实上,在非IE浏览器中,事件传播过程中的处理函数,或同一DOM节点触发的多个函数间的Event对象是全等的,这与绑定形式[addEventListener/DOM0]无关。


而在IE浏览器中,仅同一DOM节点触发的多个函数间通过参数传递的Event对象(attachEvent)是全等的。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章