在今天的課題當中,我們要針對常用的 EventTarget.addEventListener
做進一步的認識。[1]
首先我們看到 MDN 中的定義:EventTarget.addEventListener()
方法,能將指定的事件監聽器註冊到 EventTarget 實作物件上。EventTarget 可能是 Document 中的 Element 物件、Document 物件本身、Window 物件,或是其它支援事件的物件。[2]EventTarget.addEventListener()
的語法如下:
target.addEventListener(type, listener[, options]);
target.addEventListener(type, listener[, useCapture]);
capture phase
。預設為 bubbling phase
。event.preventDefault()
方法。option 參數的使用方法如下:
Event.target.addEventListener(type, function, {
capture: ture/flase,
once:true/false,
passive:true/false
});
我們已經知道 eventListener()
方法的預設模式為 bubbling phase
而不是 capture phase
,但是這兩者的差異在哪呢?
從參考網站以及 W3C 文件中,我們可以得知當一個事件被觸發的流程如下圖。[3][4]
當有一事件被觸發時,會先執行 capture phase
,然後才在我們指定的目標物件作動,最後執行 bubbling phase
。
當事件發生時,會先走 capture phase
,也就是依序通知 Document -> <html>
-> <body>
-> <table>
-> <tbody>
-> <tr>
這些父元素容器 DOM 元件有事件被觸發。
然後到達目標物件之後通知 <td>
元素,事件被觸發了。
最後進行 bubbling phase
,就是以相反的方向從 <td>
開始通知流程中的父元素容器 DOM 有事件發生。在通知完 Document 後,整個事件流程結束。
由上方的事件流程圖我們得知事件觸發時系統判斷的過程,但是如果今天我們父元素容器們與子元素呈現重疊的狀態,且都包含監聽事件,如此一來我們按下目標子元素的話,整個 DOM 上的父元素都會被觸發事件。
為了要避免這種事情發生,我們可以在執行的函式中加入 event.stopPropagation()
,藉由加入此方法,當我們事件目標執行之後,就會停止後續 capture phase
或 bubbling phase
。
在今天的課題當中,我們將經常使用到的 EventTarget.addEventListener
,做更進一步的認識,
希望透過瞭解這些背後的機制,大家在使用時可以避開更多的地雷,以上是今天的內容,感謝您的閱讀。