0%

HTML - event.target vs. event.currentTarget

學習目標

  1. 了解 event.targetevent.currentTarget 的差異。
  2. 用樹狀資料夾的情境,使用 event.currentTarget 來達成。

target 和 currentTarget 在幹麻

定義

首先,先來看看 MDN 對於這兩個功能的定義是什麼

The read-only target property of the Event interface is a reference to the object onto which the event was dispatched.

The currentTarget read-only property of the Event interface identifies the current target for the event, as the event traverses the DOM

但是,我比較喜歡這一篇文章targetcurrentTarget 的解讀,我覺得比較好懂:

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 是不會變喔,還是保持原本觸發的目標元素。

用一張圖來具現化一下上面的觸發流程
Bubbling Event

假設今天我們分別在 child, father2, father3 綁上 click 的監聽事件。

當使用者點擊最內層的 child,隨著 bubbling 的方向向外層傳遞,沿路當碰到也有綁定 click 的監聽事件的 father2 和 father3 ,currentTarget 就會從 child → father2 → father3 這樣子。

Demo

以下的範例就是加入了 currentTarget 這個功能到資料夾的開闔效果中
Demo

資料夾的樹狀畫面是長得像這樣
FileCombination

在以上的範例中的 js 檔案裡面的 processClassList 函式長得像這樣

1
2
3
4
5
6
7
8
9
10
11
12
13
const folderLevel1El = document.querySelector('.folder-level-name');
folderLevel1El.addEventListener('click', function (evt) {
return processClassList(evt);
});

function processClassList(evt) {
evt.stopPropagation();
if (!evt.currentTarget.parentElement.classList.contains('is-open')) {
...
} else {
...
}
}

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

  1. event.target 是代表觸發事件的目標元素,它在冒泡事件的傳遞過程中是不會改變的。
    event.currentTarget 是代表觸發的事件所綁定的元素,它在冒泡事件的傳遞過程中是有可能改變的喔,只要路途中有其他元素也有綁定相同的觸發事件。

  2. 可以運用 event.currentTarget 在資料夾樹狀情境中,來達到為父元素新增或刪除某些 class,進而達成資料夾開闔的效果。

Reference

  1. https://stackoverflow.com/questions/10086427/what-is-the-exact-difference-between-currenttarget-property-and-target-property
  2. currentTarget Definition
  3. target Definition
  4. elaborate the difference between target and currentTarget