JS事件对象中 target 和 currentTarget 的
好久不见!看了下上次写的JS相关文章居然还是在一年前,突然感觉自己很对不起一直关注我的朋友们,希望自己更新进度能尽量加快些吧!
今天我们就来简单谈谈JavaScript的Event事件对象中 target 和 currentTarget 两者之间的区别吧~
一、this对象
我们知道,想要获取某事件所绑定的元素,通常我们可以直接使用this
对象即可。比如:
<div id="container">
<div id="box"></div>
</div>
稍微给它们加点样式:
#container{ width: 200px; height: 200px; background-color: #f00;}
#box{ width: 100px; height: 100px; background-color: #0f0;}
页面效果如下:
其中绿色盒子id
为box
,而红色盒子id
为container
,绿盒子是红盒子的子元素。现在,我给它们分别添加点击事件,目的是获取它们的id
属性。
document.getElementById('container').onclick = function(){
alert(this.id); // 'container'
};
document.getElementById('box').onclick = function(){
alert(this.id); // 'box'
};
可以看到,只要我们给哪个元素绑定点击事件,那么事件执行时通过this
所获取到的元素就是绑定点击事件的那个元素。
但是,并不是任何时候我们都可以通过this
来获取当前绑定事件元素,比如当我们使用箭头函数或使用Vue.js框架时,this
就“失效”了。
1. 箭头函数
document.getElementById('container').onclick = () => {
alert(this); // [object Window]
alert(this.id); // undefined
};
有关箭头函数为什么会导致this
指向问题,请戳→ES6之箭头函数。
2. Vue.js
<template>
<div id="container" @click="foo">
<div id="box"></div>
</div>
</template>
<script>
export default {
data() {
return {
id: '我是data中的id'
}
},
methods: {
foo(){
alert(this); // [object Object]
alert(this.id); // '我是data中的id'
}
}
}
</script>
这里的this
指向的是当前Vue组件实例,所以this.id
自然获取的是data
中的id
而不是container
了。
那么,对于这个问题我们该如何解决呢?如何才能正确获取到当前绑定事件元素呢?
这时我们就需要用到事件对象中的target
和currentTarget
属性了。
二、target 和 currentTarget
<template>
<div id="container" @click="foo"></div>
</template>
<script>
export default {
data() {
return {
id: '我是data中的id'
}
},
methods: {
foo(e){
alert(e.target.id); // 'container'
alert(e.currentTarget.id); // 'container'
}
}
}
</script>
我们看到,通过target
和currentTarget
都成功获取到了点击事件所绑定的DOM元素,那么 target
和 currentTarget
之间又有什么区别呢?
其实,只要我们将事件处理程序直接绑定到目标元素,那么目标元素事件执行时,target
和 currentTarget
均指向的是该目标元素。然而,如果事件处理程序并未绑定在目标元素,而是在其祖先元素上时,那么target
则指向的是该目标元素,而currentTarget
指向的是当前绑定事件的祖先元素。
可能看起来比较难理解,我们还是用最开始那个例子吧。
<template>
<div id="container" @click="foo">
<div id="box"></div>
</div>
</template>
<script>
export default {
data() {
return {
id: '我是data中的id'
}
},
methods: {
foo(){
alert(e.target.id);
alert(e.currentTarget.id); // 'container'
}
}
}
</script>
此时,只要foo()
执行,那么e.currentTarget.id
的值必然是container
,因为currentTarget
永远指向的是事件所绑定的元素(这里点击事件直接绑定在container元素上)。
但是target
则不同,它指向的是事件实际执行所在的元素,所以本例中e.target.id
的值取决于鼠标直接所点击的元素。
① 鼠标直接点击container元素,也就是红色部分
这时 target
和 currentTarget
均指向的是container元素,因为事件执行的目标和事件绑定的目标是相同的,都是container元素。
alert(e.target.id); // 'container'
② 鼠标直接点击box元素,也就是绿色部分
这时 target
指向的是box元素,而 currentTarget
指向的是container元素,因为事件执行的直接目标是box元素。
alert(e.target.id); // 'box'
重点总结
① 在原生JS事件处理程序中(非箭头函数),
this
对象与事件对象中的currentTarget
指向相同
②target
指向的是事件实际执行所在的元素,currentTarget
指向的是事件所绑定的元素