在使用jQuery做事件委托时,事件对象里有两个非常容易混淆的属性:event.target和event.currentTarget。很多人写了一段委托代码,点击子元素后却发现拿到的元素和自己预想的不一致,排查半天才发现问题就出在对这两个属性的理解上。简单来说,event.target永远是事件最初被触发的那个真实目标元素,而event.currentTarget则是当前事件处理器所绑定的那个元素。本文结合事件流的传播过程,用图解加代码的方式把两者的指向规则彻底讲清楚。

一、从DOM事件流理解两个属性的本质区别
要分清这两个属性,必须先理解事件的传播路径。浏览器中一次点击事件并不是简单地发生在被点击的元素上,而是经历三个阶段:捕获阶段从document一路向下传递到目标元素,目标阶段在目标元素上触发,冒泡阶段再从目标元素逐层向上回到document。jQuery的on方法默认在冒泡阶段监听事件,事件委托正是利用了冒泡机制实现的。
在整个传播路径上,event.target的值是固定不变的,它始终指向事件最初发生的那个元素,也就是用户实际操作的那个最内层节点。而event.currentTarget则不同,它是一个动态属性,表示的是当前正在执行事件处理函数的那个元素。由于处理函数只绑定在委托容器上,所以在jQuery委托场景里,event.currentTarget就等于你调用on方法时匹配到选择器的那个元素本身。
举个直观的例子:有一个ul列表,事件绑定在ul上,委托给li处理。当用户点击li内部的span文字时,event.target是那个span,而event.currentTarget是li,jQuery会根据选择器在冒泡路径上匹配元素并把this指向它。如果点击的是li本身的空白区域,那么两个属性就都指向li。这种动态差异正是很多问题的来源。
二、用代码验证指向差异
下面用一个具体例子来验证。构造一个三层嵌套的结构:ul作为委托容器,li是条目,span是条目内的文字:
<ul id="list"> <li>第一条 <span>删除</span></li> <li>第二条 <span>删除</span></li> </ul>
然后用jQuery的on方法做事件委托:
$('#list').on('click', 'li', function (e) {
console.log('target:', e.target.tagName);
console.log('currentTarget:', e.currentTarget.tagName);
console.log('this === e.currentTarget:', this === e.currentTarget); // true
});运行后点击li中的文字,控制台输出target: SPAN和currentTarget: LI;点击li的空白处,两者都会输出LI。这验证了前面的结论:this在jQuery委托中与event.currentTarget等价,都指向选择器匹配到的元素。如果业务逻辑需要拿到条目本身,正确做法是使用$(this)或$(e.currentTarget),而不是$(e.target),后者在点击到span时会让你拿到错误的元素。
再看一个原生对比,帮助理解jQuery做了什么包装。原生写法中委托通常是:
document.getElementById('list').addEventListener('click', function (e) {
if (e.target.tagName === 'SPAN') {
var li = e.target.closest('li');
console.log('条目是', li.textContent);
}
});原生场景下event.currentTarget永远等于绑定监听的ul,因为处理函数就在ul上执行,浏览器不会帮你做选择器匹配;而jQuery的委托机制内部会在冒泡路径上逐层检查节点是否匹配传入的li选择器,匹配到后调用处理函数并把this指向该li,这就是两者表现不同的根源。
三、实际开发中的典型陷阱与正确用法
最常见的陷阱是在判断点击来源时误用event.target做逻辑分支。比如一个列表中点击条目打开详情、点击条目内按钮删除数据,如果统一用$(e.target)去取数据,当用户点在按钮上时可能取到按钮而点在文字上时取到span,导致取值逻辑混乱。正确做法是先用$(e.currentTarget)或$(this)确定条目容器,再用$(e.target).closest('button')判断具体操作:
$('#list').on('click', 'li', function (e) {
var $li = $(this);
var $btn = $(e.target).closest('button');
if ($btn.length) {
console.log('删除条目:', $li.index());
} else {
console.log('打开条目:', $li.text());
}
});另一个陷阱是在阻止事件传播时混淆两者。e.stopPropagation()阻止的是事件继续冒泡,不会改变event.target的值;而如果在非委托绑定(直接绑定在按钮上)的场景下处理事件,此时event.target和event.currentTarget才会完全一致,都等于绑定元素本身。理解了这一点,就能在直接绑定与委托绑定之间自由切换而不出错。
总结一下记忆口诀:target看用户点在哪,currentTarget看代码绑在哪。委托场景下前者随时可能变化,点到的子元素不同结果就不同,后者固定为选择器匹配的元素。分清这两个指向,事件委托相关的绝大多数问题都能迎刃而解。
event.targetevent.currentTargetjQuery事件委托修改时间:2026-09-09 05:12:42