最近做项目,使用事件代理时,需要获取点击事件的当前元素,首先想到的就是currentTarget,单从字面意思理解,currentTarget就是当前目标。但是使用的时候,父子元素中,点击子元素时,发现事件冒泡到父元素时,currentTarget指向了父元素。这是为什么呢?下面来细说一下。
首先来说一下,事件冒泡和事件捕获。IE是事件冒泡,而w3c提出的是事件捕获。简单来说事件冒泡就是从最具体的元素冒泡到最不具体的元素,而事件捕获恰恰相反,是从最不具体的元素逐层捕获到最具体的元素。而浏览器接收事件的顺序是先捕获再冒泡,即事件捕获=》目标阶段=》事件冒泡。而接收事件的范围,是window=》document=》html=》head/body=》具体元素。不管是事件冒泡,还是事件捕获,都是发生在父子元素之间,即从外层到内层,或者从内层到外层。我们在开发过程中多用事件冒泡,但现在的主流浏览器默认是捕获,但通常我们在使用addEventListener这个方法的时候他的第三个参数还是会显示的指定为false,即为不捕获。冒泡和捕获决定了事件执行的时机,假如你在冒泡阶段注册了一个事件,那么在捕获阶段即使捕获到了这个事件,也不会去执行。看下面的栗子🌰:
<div id="grandpa">
<div id="father">
<div id="son"></div>
</div>
</div>
grandpa.addEventListener("click", function () {
console.log("grandpa");
}, false);
father.addEventListener("click", function () {
console.log("father");
}, false);
son.addEventListener("click", function () {
console.log("son");
}, true);
点击时,发现打印的顺序是son-father-grandpa。son的第三个参数为true,所以在捕获阶段会被触发,而其他两个位false,只有在冒泡阶段才会触发。
说了这么多,接下来进入正题,target和currentTarget的区别:
1.target是触发事件的具体对象,只会在事件流的目标阶段。
2.currentTarget是绑定事件的对象,可能出现在事件流的任意阶段。
3.通常情况下,target和currentTarget都是指向同一个对象,用target即可。但是要注意的是在父子嵌套的关系中,绑定事件的对象是父元素,单击子元素,只要不阻止事件流,父元素也会执行这个事件。这时,currentTarget指向父元素,而target指向子元素。