事件冒泡

事件冒泡

一个问题​

如果有下面一段代码:

在 HTML 中,定义了嵌套的 3 个

,ID 分别为 div1、div2、div3。

在 JavaScript 中定义一个点击事件处理函数,打印当前执行事件元素的 id。

把事件处理函数分别注册到这 3 个 div 中。

这个时候,如果点击最里边的 div3 元素,你猜代码的输出结果是什么?

// html:

div1

div2

div3

;

// javascript:

function handleClick(event) {

console.log(event.currentTarget.id);

}

for (let i = 1; i <= 3; i++) {

let div = document.getElementById(`div${i}`);

div.addEventListener("click", handleClick);

}

选项

A.

div3

B.

div3, div2, div1

答案是:B。 为什么结果会是这样呢?这得从 JavaScript 的事件冒泡机制说起。

什么是事件冒泡机制​

事件冒泡机制是说,在给某个 DOM 元素设置了事件监听器之后,例如鼠标点击事件,在触发事件时,浏览器不仅仅执行该元素的事件处理函数,还会顺着 DOM 树的结构,一级一级的往上查找,是不是有父级元素注册了相同的事件监听器,如果有的话,还会执行父级元素的事件处理函数,直到 根元素为止。

在上边的例子中,点击了 div3 元素之后:

先执行了 div3 的点击事件处理函数,此时 event.currentTarget 是 div3 这个元素,打印出它的 id 为 div3。

接着浏览器会查找上级元素 div2 有没有点击事件监听,结果有,那么就执行了它的处理函数打印出 div2。

同理,打印出最外层的 div1 之后,就再没有点击事件监听了,这个时候事件才停止冒泡了。

阻止事件冒泡机制​

事件冒泡机制会给开发中带来意想不到的结果,要阻止它也很简单,只需要在事件处理函数中,调用事件参数的 stopPropagation() 方法,这样事件在当前元素处理完成之后就结束了,不会再查找父级组件相同的事件监听了。

event.stopPropagation();

如果我们在之前的例子中,事件处理函数里,加上这段代码,那么,再点击最里边的 div3,就只会打印出 div3 了:

function handleClick(event) {

event.stopPropagation();

console.log(event.currentTarget.id);

}

对于一些老的浏览器,例如 IE9 以下,如果要阻止事件冒泡,需要设置 event 参数的 cancelBubble 属性为 true:

event.cancelBubble = true;

这样也就阻止事件冒泡了。如果以后遇到了同时触发了多个事件的情况,可以先想一下是不是事件冒泡机制捣的鬼,如果是就把它停止。

转载:JavaScript事件冒泡机制 - 峰华前端工程师 (zxuqian.cn)

相关推荐