addEventListener()中的第三个参数

昨天遇到一段js代码里面的addEventListener方法竟然有三个参数,去谷歌搜了一下,觉得这个概念很有意思,值得总结一下写成博客。

useCapture

addEventListener()中的第三个参数是Boolean类型的值,代表第二个参数handler是否在第一个参数Event的capture阶段使用。

事件(Event)在事件目标(EventTarget)中的顺序

当DOM元素之间有包含关系时,发生在其上的事件有两种顺序:

  • Capturing
  • Bubbling

Capturing就是从上往下:

               | |
---------------| |-----------------
| element1     | |                |
|   -----------| |-----------     |
|   |element2  \ /          |     |
|   -------------------------     |
|        Event CAPTURING          |
-----------------------------------

这种情况下,事件发生后,注册在element1上的handler会先触发,注册在element2上的handler会后触发。

Bubbling就是从下往上:

              / \
---------------| |-----------------
| element1     | |                |
|   -----------| |-----------     |
|   |element2  | |          |     |
|   -------------------------     |
|        Event BUBBLING           |
-----------------------------------

这种情况下,事件发生后,注册在element2上的handler会先触发,注册在element1上的handler会后触发。

W3C标准中的事件顺序

                 | |  / \
-----------------| |--| |-----------------
| element1       | |  | |                |
|   -------------| |--| |-----------     |
|   |element2    \ /  | |          |     |
|   --------------------------------     |
|        W3C event model                 |
------------------------------------------

在w3c模型中,事件会先从上往下,到事件目标元素后,再从下往上,一直到最外面的元素。

代码实例

<div id="parent">parent div
    <div id="child">child div</div>
</div>
const parent = document.querySelector('#parent');
const child = document.querySelector('#child');

function first() {
    alert('first');
}
function second() {
    alert('second');
}

parent.addEventListener('click', second, false);
child.addEventListener('click', first);

点击child元素,会先弹出first,然后弹出second。我们来分析一下为什么会这样:
click事件在child元素发生后,第一步是capturing阶段,先从上往下寻找child元素的锚定元素(Ancestor Element)中是否有可以触发的handler,如果useCapture参数是true的话就会在此阶段触发,结果发现没有可以触发的handler。
click事件到达child元素后触发first方法,然后开始bubbling阶段,到达parent元素时发现有用于此阶段的handler,触发second方法。

如果我们把代码改一下,变成:

parent.addEventListener('click', second, true);
child.addEventListener('click', first);

点击child元素,会先弹出second,然后弹出first。分析过程和前面很类似:
click事件在child元素发生后,第一步是capturing阶段,先从上往下寻找child元素的锚定元素(Ancestor Element)中是否有可以触发的handler,发现可以触发second。
click事件到达child元素后触发first方法,然后开始bubbling阶段,到达parent元素时发现有用于此阶段的handler,没有发现可以触发的handler。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章