捕获与冒泡,是 js 事件传播的相关概念。当一个元素及其父元素,父元素的父元素等身上绑定了多个点击事件时,它们规定了这些事件的执行线索。

1.预备知识1:onclick与addEventListener的区别

onclick:只能定义一个点击事件,若重复定义,最后一次会覆盖前面所有定义

addEventListener:可以添加多个点击事件,并按定义顺序执行

2.预备知识2:当我们点击元素时,我们都点了什么?

a:我们点击了该元素,以及该元素的父亲、爷爷等所有祖先

好,现在进入正题——假设我们有一个元素,该元素、元素的父亲、元素的爷爷都绑定了点击事件。现在我们点一下它,问:

1:三个元素的点击事件会不会都触发?

2:如果会,它们按什么样的顺序执行?

a1:会

a2:回答这个问题,我们需要的知识,就是捕获与冒泡

3.addEventListener的第三参数

通常我们写点击事件的监听器,语法是这样的

addEventListener('click', function(){})

然而这个api还有第三个参数,一个逻辑变量

addEventListener('click', function(){}, Boolean)

对于这个参数,我们先记住一个结论:这个变量如果为True,就将监听器加入捕获流;如果为False,分配到冒泡流。(缺省情形默认为False)

4.捕获与冒泡

当我们点击一个元素的时候,绑定在该元素及其所有祖先上面的事件,会按照“先捕获,后冒泡”的顺序执行。如下:

捕获阶段:从祖先到儿子,检查是否有分配到捕获流的监听器,若有→触发点击

冒泡阶段:从儿子到祖先,检查是否有分配到冒泡流的监听器,若有→触发点击

例如:

队列1就是捕获流,队列2就是冒泡流

例外规则

对于最底层元素身上的监听器,js有一个“潜规则“——就是不按true跟false,直接遵循定义顺序执行

例如:

可以看到:执行顺序不是“爷爷捕获 儿子捕获 儿子冒泡 爸爸冒泡”,

而是“爷爷捕获 儿子冒泡 儿子捕获 爸爸冒泡”。

这是因为儿子是最底层元素

记住这点

5.总结

捕获与冒泡,是解决元素点击事件执行顺序的线索。

点击事件的执行顺序:

1:先捕获,后冒泡

2:捕获为true,自上而下;冒泡为false,由下至上