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。

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