前端开发让前端飞Web前端之路

JS事件对象中 target 和 currentTarget 的

2020-05-10  本文已影响0人  前端王睿

好久不见!看了下上次写的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;}

页面效果如下:


其中绿色盒子idbox,而红色盒子idcontainer,绿盒子是红盒子的子元素。现在,我给它们分别添加点击事件,目的是获取它们的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了。

那么,对于这个问题我们该如何解决呢?如何才能正确获取到当前绑定事件元素呢?

这时我们就需要用到事件对象中的targetcurrentTarget属性了。

二、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>

我们看到,通过targetcurrentTarget都成功获取到了点击事件所绑定的DOM元素,那么 targetcurrentTarget 之间又有什么区别呢?

其实,只要我们将事件处理程序直接绑定到目标元素,那么目标元素事件执行时,targetcurrentTarget 均指向的是该目标元素。然而,如果事件处理程序并未绑定在目标元素,而是在其祖先元素上时,那么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元素,也就是红色部分

这时 targetcurrentTarget 均指向的是container元素,因为事件执行的目标和事件绑定的目标是相同的,都是container元素。

alert(e.target.id);  //  'container'

② 鼠标直接点击box元素,也就是绿色部分

这时 target 指向的是box元素,而 currentTarget 指向的是container元素,因为事件执行的直接目标是box元素。

alert(e.target.id);  //  'box'

重点总结

① 在原生JS事件处理程序中(非箭头函数),this对象与事件对象中的currentTarget指向相同
target指向的是事件实际执行所在的元素,currentTarget指向的是事件所绑定的元素

上一篇下一篇

猜你喜欢

热点阅读