初學者必學:搞懂 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 元素物件

也就是說,它的型別是 HTMLElementElement,根據實際觸發事件的 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 / DOMHTML 原始碼
表示什麼使用者目前輸入的內容頁面初次載入時的預設值
是否會被同步更新?❌ 不會需手動用 .setAttribute() 修改

這也說明了為什麼你會看到:

input.value = "新的值";
input.getAttribute("value"); // 仍然是原本的預設值

event.targetevent.currentTarget 的差異

在事件處理中,event.targetevent.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,你就能寫出更聰明、更有彈性的事件處理邏輯,無論是製作互動元件、表單驗證,還是實作拖曳、動態清單等功能,都會事半功倍!

Similar Posts