學習目標
- 了解
event.target
和event.currentTarget
的差異。 - 用樹狀資料夾的情境,使用
event.currentTarget
來達成。
target 和 currentTarget 在幹麻
定義
首先,先來看看 MDN 對於這兩個功能的定義是什麼
The read-only
target
property of theEvent
interface is a reference to the object onto which the event was dispatched.
The
currentTarget
read-only property of theEvent
interface identifies the current target for the event, as the event traverses the DOM
但是,我比較喜歡這一篇文章對 target
和 currentTarget
的解讀,我覺得比較好懂:
event.target
: refers to the element that triggered the event (即: 使用者互動的那個元素)
event.currentTarget
: refers to the element that the event is attached to
由上面的定義我們可以看出來 event.target
專指觸發該事件的元素 (notice: 它不一定是有綁定該觸發事件的元素喔) 。
而 event.currentTarget
是指有綁定該觸發事件的元素,這句話有點難理解,讓我再講清楚一點。
當我們點擊子元素的時候,會觸發擷取 (capture) 和冒泡 (bubbling) 事件,這邊我們只先看冒泡事件,冒泡事件觸發的順序會由最內層,也就是從觸發事件的目標元素一路跑到最外層的 document,而這一路上若有任何元素綁定了跟目標元素相同的觸發事件的時候,此時,event.currentTarget
會變成這個元素,而 event.target
是不會變喔,還是保持原本觸發的目標元素。
用一張圖來具現化一下上面的觸發流程
假設今天我們分別在 child, father2, father3 綁上 click 的監聽事件。
當使用者點擊最內層的 child,隨著 bubbling 的方向向外層傳遞,沿路當碰到也有綁定 click 的監聽事件的 father2 和 father3 ,currentTarget 就會從 child → father2 → father3 這樣子。
Demo
以下的範例就是加入了 currentTarget
這個功能到資料夾的開闔效果中
Demo
資料夾的樹狀畫面是長得像這樣
在以上的範例中的 js 檔案裡面的 processClassList 函式長得像這樣
1 | const folderLevel1El = document.querySelector('.folder-level-name'); |
currentTarget 使用情境
上面的程式碼中,我們為 class 是 folder-level-name 的 DOM 綁定了一個 click 監聽事件,並觸發 processClassList 函式。
在這個函式我們是使用了 currentTarget ,代表會取得綁定該 click 事件的元素,也就是 folder-level-name。
若我們點擊了 folder-level-name 的子元素,childEl-1 或 childEl-2,此時,就會觸發 folder-level-name 的 click 事件。而我們就可以在 processClassList 使用 currentTarget 來取得 folder-level-name 元素,並為它的父元素來加上 is-open 的 class 內容,以此達成開闔資料夾的效果。
但如果你把 target 改成 currentTarget 的話,當你點擊 childEl-1 就會取得 childEl-1 若點擊 childEl-2 就會取得 childEl-2 這個元素,就要特別注意,你要為哪一個 DOM 加上 is-open 來達成資料夾的開闔效果囉。
Conclusion
event.target
是代表觸發事件的目標元素,它在冒泡事件的傳遞過程中是不會改變的。event.currentTarget
是代表觸發的事件所綁定的元素,它在冒泡事件的傳遞過程中是有可能改變的喔,只要路途中有其他元素也有綁定相同的觸發事件。可以運用
event.currentTarget
在資料夾樹狀情境中,來達到為父元素新增或刪除某些 class,進而達成資料夾開闔的效果。