初學者必學:搞懂 JavaScript 的 event.target
更新日期: 2025 年 4 月 23 日
在學 JavaScript 的過程中,處理使用者互動是很重要的一環。
無論是點擊按鈕、輸入文字,甚至是滑鼠滑過畫面,這些行為在網頁上都被稱為「事件」。
而當你透過 JavaScript 捕捉這些事件時,總會收到一個 event
物件,而其中最常用、也最關鍵的屬性之一就是 event.target
。
但這個屬性到底是什麼?為什麼它可以讓我們知道「使用者點了誰」?它又和我們熟知的 JavaScript 物件有什麼關係?本文將從零開始,帶你理解這一切。
event.target
是什麼?
當使用者觸發事件(例如點擊、輸入等)時,JavaScript 會自動將該事件的詳細資訊打包成一個 event
物件傳進你的處理函式中。
這個物件裡包含了許多資料,而其中的 target
屬性,就是指向當下被使用者實際操作的那個元素。
✅ 範例
<button>點我</button>
document.querySelector("button").addEventListener("click", function (event) {
console.log(event.target); // 👉 被點擊的那顆按鈕
});
這段程式中,當你點下按鈕,event.target
就會是那顆 <button>
元素。
event.target
是什麼型別?
你可能會好奇,這個 event.target
是什麼型別的資料?是字串嗎?還是函式?
答案是:它是一個 DOM 元素物件。
也就是說,它的型別是 HTMLElement
或 Element
,根據實際觸發事件的 HTML 元素而定。
你可以把它想像成 JavaScript 中的一個物件,但這個物件是代表畫面上的某個 HTML 元素,並具備許多操作功能。
🔹為什麼 HTML 會變成 JavaScript 的物件?
這裡就得提到一個核心觀念:DOM(Document Object Model)。
當瀏覽器載入一份 HTML 文件時,會自動把 HTML 的內容「轉換成一棵物件樹」,這棵樹就叫做 DOM。這棵 DOM 樹中,每個 HTML 元素都會被變成一個可以用 JavaScript 操作的物件,也就是我們常說的 DOM 元素。
所以,當你在 JavaScript 中這樣寫:
const el = document.getElementById("greeting");
即使原本只是這樣一段 HTML:
<p id="greeting">哈囉</p>
el
就會是一個物件。你可以像操作一般 JavaScript 物件一樣操作它:
el.textContent = "你好,世界";
el.style.color = "red";
el.setAttribute("data-type", "info");
這一切就是因為瀏覽器已經幫我們把 HTML 結構轉成了 JavaScript 能操作的 DOM 結構
回到 event.target
:既然是 DOM 元素,那它能做什麼?
因為 event.target
是一個 DOM 元素,所以它具備許多實用的屬性與方法,像是:
.tagName
:取得元素的標籤名稱(如 “BUTTON”).id
、.classList
:操作元素的屬性與類別.textContent
:取得或改變文字內容.style
:修改元素樣式.setAttribute()
:設定 HTML 屬性
你可以用這段程式驗證它的型別與功能:
document.querySelector("button").addEventListener("click", function (event) {
console.log(typeof event.target); // "object"
console.log(event.target instanceof HTMLElement); // true
console.log(event.target.tagName); // "BUTTON"
});
🔹 5. 那 .value
和 .name
呢?什麼時候會出現在 event.target
上?
在你使用 event.target
時,常會看到人們讀取 .value
和 .name
屬性,但這兩個屬性並不是每個 DOM 元素都有。它們只存在於「表單元素」上。
✅ 有 .value
和 .name
的情況
<input type="text" name="username" placeholder="輸入名字" />
document.querySelector("input").addEventListener("input", function (event) {
console.log(event.target.name); // "username"
console.log(event.target.value); // 使用者輸入的文字
});
這是因為 <input>
、<select>
、<textarea>
等元素在 DOM 中都有 .value
和 .name
這些屬性,是瀏覽器內建提供的。
❌ 沒有 .value
的情況
如果你點到的是一般元素,例如:
<div id="box" name="testBox">我是區塊</div>
document.getElementById("box").addEventListener("click", function (event) {
console.log(event.target.name); // "testBox"(有設定 name 才會有)
console.log(event.target.value); // undefined(div 沒有 value 屬性)
});
在這種情況下,.value
就是 undefined
,因為 <div>
並不是一個可以「輸入內容」的元素。
HTML 沒寫 value
屬性,為什麼 .value
還是存在?
這也是初學者常見的疑問:我明明沒在 HTML 裡面寫 value="..."
,為什麼 JavaScript 還是可以存取 .value
?
答案在於:DOM 中的 .value
屬性和 HTML 裡的 value
屬性是兩回事。
<input type="text" name="username" />
const input = document.querySelector("input");
console.log(input.value); // ""(一開始是空字串)
input.value = "Hello!";
console.log(input.value); // "Hello!"
即使你沒寫 value="..."
,.value
屬性依然存在,並預設為空字串。它表示「目前的輸入值」,而不是 HTML 載入時的預設值。
🧠 .value
(屬性) vs value="..."
(HTML 屬性)
項目 | .value (JS) | value="..." (HTML) |
---|---|---|
設定位置 | JavaScript / DOM | HTML 原始碼 |
表示什麼 | 使用者目前輸入的內容 | 頁面初次載入時的預設值 |
是否會被同步更新? | ❌ 不會 | 需手動用 .setAttribute() 修改 |
這也說明了為什麼你會看到:
input.value = "新的值";
input.getAttribute("value"); // 仍然是原本的預設值
event.target
與 event.currentTarget
的差異
在事件處理中,event.target
和 event.currentTarget
是兩個看起來很像、但用途完全不同的屬性。
許多初學者一開始學事件監聽時常常混淆這兩者,理解清楚這個差異,對撰寫乾淨且可維護的互動邏輯非常重要。
📌 event.target
是「被點到的那個元素」
當使用者觸發一個事件時,真正觸發的那個元素,會被放在 event.target
中。它代表的是「事件源頭」,也就是畫面上使用者實際互動的那個元素。
📌 event.currentTarget
是「你綁定監聽器的元素」
而 event.currentTarget
則是指「事件監聽器所在的元素」。換句話說,它是你寫 addEventListener()
的那個 DOM 節點——不管使用者點到的是這個元素本身,還是它的子元素,currentTarget
永遠是你加監聽器的地方。
實際範例
假設你有以下 HTML 結構:
<ul id="menu">
<li>首頁</li>
<li>關於我們</li>
<li>聯絡方式</li>
</ul>
你在 <ul>
元素上綁定了一個點擊事件監聽器:
document.getElementById("menu").addEventListener("click", function (event) {
console.log("event.target:", event.target); // 點到哪一個 <li>
console.log("event.currentTarget:", event.currentTarget); // 永遠是 <ul>
});
🧪 假設你點了「關於我們」
event.target
會是那個被點到的<li>
(裡面顯示「關於我們」)event.currentTarget
則仍然是整個<ul>
,因為監聽器是綁在#menu
上的
這種寫法就是所謂的「事件委派(event delegation)」:你只在父層 <ul>
綁定事件,但卻能捕捉到底是哪一個 <li>
被點了。
🧠 為什麼會有這兩個屬性?
因為事件在瀏覽器裡是「冒泡」的。
當你點擊某個子元素時,事件不只會在那個元素觸發,還會一層一層往上傳遞到父元素,最終傳到整個 document
。而 event.currentTarget
就是用來讓你知道這段程式碼實際是在哪一層被呼叫的。
比較表一覽
屬性名稱 | 說明 |
---|---|
event.target | 實際觸發事件的元素(被點到的那個元素) |
event.currentTarget | 綁定事件監聽器的元素(你加 .addEventListener 的那個) |
🎯 使用建議
- 如果你需要知道「使用者點了哪一個項目」,就用
event.target
- 如果你只想針對「我在哪裡加了監聽器」做事情,就用
event.currentTarget
- 在實作事件委派(event delegation)時,兩者通常會一起用
✅ 範例應用:只處理被點到的 <li>
,其他忽略
document.getElementById("menu").addEventListener("click", function (event) {
if (event.target.tagName === "LI") {
console.log("你點的是:", event.target.textContent);
}
});
這樣做的好處是:你只需要在 <ul>
上加一次監聽器,就能處理所有 <li>
的點擊事件,未來如果有新的 <li>
被動態加入也不用重新加監聽器。
event.target
的實作應用:實用又彈性的互動處理技巧
理解了 event.target
的概念之後,接下來我們要看看它在實務開發中的應用。
這裡會介紹兩個常見場景,分別是「表單輸入變更監聽」與「多按鈕點擊處理」,你會發現 event.target
能讓事件處理更靈活、更簡潔。
範例 1:即時監聽使用者輸入內容
表單欄位(如 <input>
)是最常與使用者互動的地方,而 event.target
可以幫我們即時取得使用者正在輸入的內容。
📌 HTML:
<input type="text" name="username" placeholder="輸入名字" />
📌 JavaScript:
document.querySelector("input").addEventListener("input", function (event) {
console.log("你輸入了:", event.target.value);
});
💡 解說:
- 當使用者在輸入框中打字,每打一個字就會觸發一次
input
事件。 event.target
就是那個<input>
元素。.value
是使用者輸入的內容,即時變化。
這種寫法適用於表單驗證、搜尋提示(autocomplete)、即時表單儲存等功能。
範例 2:多個按鈕共用一個事件監聽器
你有一組功能按鈕,例如「新增」、「編輯」、「刪除」,如果每個都加上 addEventListener()
,不但麻煩,還會降低效能。這時就可以利用「事件委派(event delegation)」搭配 event.target
一次搞定!
📌 HTML:
<div id="btn-group">
<button>新增</button>
<button>編輯</button>
<button>刪除</button>
</div>
📌 JavaScript:
document.getElementById("btn-group").addEventListener("click", function (event) {
if (event.target.tagName === "BUTTON") {
console.log("你點的是:", event.target.textContent);
}
});
💡 解說:
- 事件監聽器只綁在父層
#btn-group
。 - 透過
event.target
判斷被點擊的是哪個<button>
。 - 這就是事件委派:由父層統一處理子元素的事件。
使用 event.target
的最佳實踐
event.target
非常強大,但若使用不當也可能導致程式碼難以維護或效能低落。以下是幾個重要的實作建議:
一定要確認元素類型再操作
因為事件可能來自父層或其他元素,操作之前務必判斷 event.target
是你預期的那個元素類型。常見做法有:
if (event.target.tagName === 'BUTTON') { ... }
if (event.target.classList.contains('submit')) { ... }
這能避免誤操作,讓邏輯更明確、安全。
事件監聽器盡量綁在容器上,用 event.target
區分
這就是事件委派的原則。比起每個按鈕都各自加一個監聽器,更推薦這樣做:
document.querySelector("#container").addEventListener("click", (event) => {
if (event.target.matches(".action-btn")) {
// 統一處理所有具有 action-btn 類別的按鈕
}
});
這種做法的優點是:
- 容易維護
- 可支援動態加入的按鈕
- 效能更佳(監聽器數量少)
不要對每個小元素都加監聽器
這樣做雖然「當下直觀」,但會造成:
- 效能浪費(監聽器數量暴增)
- 不好維護(HTML 改動時 JS 也要同步改)
- 無法支援動態生成元素(像是 Ajax 或
appendChild
產生的元素)
改用事件委派+event.target
,是更理想的策略。
總結
重點 | 說明 |
---|---|
event.target | 被操作的「實際元素」 |
典型應用 | 點擊按鈕、輸入欄、事件委派、動態 DOM 元素辨識 |
與 currentTarget 比較 | currentTarget 是「誰綁監聽器」,target 是「誰被點」 |
掌握 event.target
,你就能寫出更聰明、更有彈性的事件處理邏輯,無論是製作互動元件、表單驗證,還是實作拖曳、動態清單等功能,都會事半功倍!