在DOM事件对象中有两个属性总是时不时的困扰我,就是
target
和
currentTarget
,有时候很迷惑分不清两者的区别,因此有必要把这两个属性好好梳理一下,加深理解,以便日后的查询。
MDN中对
target
的解释为,一个触发事件的对象的引用, 当事件处理程序在事件的冒泡或捕获阶段被调用时。
而对于currentTarget,它指的是当事件遍历DOM时,标识事件的当前目标。它总是引用事件处理程序附加到的元素,而不是
event.target
,它标识事件发生的元素。
举个例子来说明。
事件冒泡阶段
<!DOCTYPE html>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<li>hello 1</li>
<li>hello 2</li>
<li>hello 3</li>
<li>hello 4</li>
<script>
let ul = document.querySelectorAll('ul')[0]
let aLi = document.querySelectorAll('li')
ul.addEventListener('click',function(e){
let oLi1 = e.target
let oLi2 = e.currentTarget
console.log(oLi1) // 被点击的li
console.log(oLi2) // ul
console.og(oLi1===oLi2) // false
</script>
</body>
</html>
我们知道,
e.target
可以用来实现
事件委托
,该原理是通过事件冒泡(或者事件捕获)给父元素添加事件监听,e.target指向引发触发事件的元素,如上述的例子中,
e.target
指向用户点击的
li
,由于事件冒泡,
li
的点击事件冒泡到了
ul
上,通过给
ul
添加监听事件而达到了给每一个
li
添加监听事件的效果,而
e.currentTarget
指向的是给绑定事件监听的那个对象,即
ul
,从这里可以发现,
e.currentTarget===this
返回
true
,而
e.target===this
返回
false
。
e.currenttarget
和
e.target
是不相等的。
事件目标阶段
我们知道,在DOM事件流中分为几个不同的阶段,如图
上述例子是事件冒泡阶段,
e.currenttarget
和
e.target
是不相等的,但是在事件的目标阶段,
e.currenttarget
和
e.target
是相等的。
<!DOCTYPE html>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<li>hello 1</li>
<li>hello 2</li>
<li>hello 3</li>
<li>hello 4</li>
<script>
let ul = document.querySelectorAll('ul')[0]
let aLi = document.querySelectorAll('li')
for(let i=0;i<aLi.length;i++){
aLi[i].addEventListener('click',function(e){
let oLi1 = e.target
let oLi2 = e.currentTarget
console.log(oLi1) // li
console.log(oLi2) // li
console.og(oLi1===oLi2) // true
</script>
</body>
</html>
在本例中,事件的目标阶段即
li
,由于
e.currentTarget
始终指向添加监听事件的那个对象,即
aLi[i]
,也就是HTML中的
li
,而
e.target
指向触发事件监听的那个对象,也是
li
,因此
e.target
和
e.currentTarget
相等,同时也和
this
相等。
因此不必记什么时候
e.currentTarget
和
e.target
相等,什么时候不等,理解两者的究竟指向的是谁即可。
e.target
指向触发事件监听的对象。
e.currentTarget
指向添加监听事件的对象。