回想起本身學習事件模式那會兒,怎麼都記不住事件的傳播流程和 addEventListener 的設置細節,後來發現好的圖片更能能幫助咱們理解邏,因此作了一個 GIF。javascript
假設咱們如今有三個DOM
節點,而且假設 div 爲根節點。(一般事件的捕獲會從根節點開始)java
而後咱們爲這些DOM
節點設置好監聽。瀏覽器
// 設置第三個參數爲 true 則在捕獲階段觸發
div.addEventListener('click', null, true);
p.addEventListener('click', null, true);
span.addEventListener('click', null, true);
span.addEventListener('click', null);
p.addEventListener('click', null);
div.addEventListener('click', null);
複製代碼
如今咱們點擊span
,那麼click
事件會被觸發,事件會從div
進入捕獲階段,從父級向子級傳遞,到達事件目標後進入冒泡階段,從子級像父級傳遞。學習
(click)span => div -> p -> span -> span -> p -> divspa
若是咱們點擊p
,那麼事件目標爲p
元素,事件從div
元素開始捕獲,並從p
元素處折返變爲冒泡。code
(click)p => div -> p -> p -> divcdn
若是在一個節點上屢次綁定同一個事件的監聽,它們會按照事件傳播流程進行(先捕獲後冒泡),若是所處流程同樣則按照先綁定先觸發的原則。對象
// 設置第三個參數爲 true 則在捕獲階段觸發
div.addEventListener('click', null, true) // #1
div.addEventListener('click', null) // #2
div.addEventListener('click', null, true) // #3
p.addEventListener('click', null, true);
p.addEventListener('click', null);
複製代碼
(click)p => div#1 -> div#3 -> p -> p -> div#2blog
雖然申明的順序是div#1
div#2
div#3
,可是捕獲先於冒泡,因此 div#1
div#3
依次觸發,而div#2
在冒泡過程當中觸發。事件
這是Event
對象的一個方法,用來阻止事件進一步傳播。
// 設置第三個參數爲 true 則在捕獲階段觸發
// #1
div.addEventListener('click', function (event) {
event.stopPropagation();
}, true)
div.addEventListener('click', null) // #2
div.addEventListener('click', null, true) // #3
p.addEventListener('click', null, true);
p.addEventListener('click', null);
複製代碼
(click)p => div#1 -> div#3
使用了stopPropagation()
以後,事件就不能進一步傳播了,即便是在div
上,捕獲和冒泡被認爲是兩個步驟,因此在捕獲階段傳播被阻止時同節點上的冒泡也不會觸發。
這是Event
對象的一個方法,一旦調用這個方法,則該元素上未觸發的監聽都不會被觸發,事件也不會進一步傳播。
如今咱們在div
上再多增長一個事件監聽,並把stopImmediatePropagation
添加在捕獲事件中第二個觸發的監聽上。
// 設置第三個參數爲 true 則在捕獲階段觸發
div.addEventListener('click', null, true) // #1
div.addEventListener('click', null) // #2
// #3
div.addEventListener('click', function (e) {
e. stopImmediatePropagation();
}, true)
div.addEventListener('click', null, true) // #4
p.addEventListener('click', null, true);
p.addEventListener('click', null);
複製代碼
(click)p => div#1 -> div#3
使用了stopImmediatePropagation()
以後,連當前節點中等待觸發的監聽都沉默了。
在比較新的瀏覽器中,addEventListener
支持更多參數配置,第三個參數類型支持object
。
target.addEventListener(type, listener[, options]);
這個 options 支持三個字段
Boolean
是否在捕獲模式觸發Boolean
是否僅觸發一次Boolean
是否使用被動模式這裏展現一下once
的效果
// 設置第三個參數爲 true 則在捕獲階段觸發
div.addEventListener('click', null, true);
p.addEventListener('click', null, true);
span.addEventListener('click', null, true);
span.addEventListener('click', null);
p.addEventListener('click', null, {once: true}); // 在冒泡階段只觸發一次
div.addEventListener('click', null);
複製代碼
(click)span => div -> p -> span -> span -> p -> div
(click)span => div -> p -> span -> span -> div
若是喜歡文章 請留下一個贊~ 若是喜歡文章 分享給更多人~
自由轉載-非商用-非衍生-保持署名(創意共享3.0許可證) 轉載時請保留原文連接 以保證可及時獲取對文章的訂正和修改