Skip to content

2026-07-05

/ 12 分鐘閱讀

/ You Might Not Need a Framework

addEventListener 選項、移除事件與自訂事件

上一篇比較了 onevent 屬性與 addEventListener 的差異,並說明後者在應用程式開發中的優勢。這篇繼續深入 addEventListener 的進階選項,以及移除事件監聽器和自訂事件的使用方式。

addEventListener 的第三個參數:選項物件

addEventListener 可以接受第三個可選參數,傳入一個選項物件來調整事件監聽的行為。

javascript
const options = {
  once: true,
  passive: true
};
element.addEventListener("load", eventHandler, options);

once

once: true 表示這個事件處理函式只會被執行一次,執行後瀏覽器會自動將它移除。不需要手動呼叫 removeEventListener

這個選項不適合像按鈕這樣需要重複點擊的元素,但在「只需要發生一次」的場景下很實用。

passive

passive: true 和執行緒與渲染效能有關。

瀏覽器的渲染與 JavaScript 共用同一條主執行緒。以滾動事件為例:當使用者滑動手指滾動頁面時,瀏覽器預設會等待 JavaScript 的事件處理函式執行完畢,確認是否有 DOM 變動需要重新佈局,才繼續移動畫面。這個等待會讓滾動感覺不順暢。

設定 passive: true 是告訴瀏覽器:「這個事件處理函式不會修改 DOM,你可以直接繼續渲染,不需要等我。」瀏覽器因此可以同步進行渲染,讓滾動更流暢。

removeEventListener:何時需要移除事件?

removeEventListener 讓你手動取消一個已掛載的事件監聽器。

但並非所有情況都需要主動移除事件。當使用者離開頁面或關閉瀏覽器時,JavaScript 環境會自動清理,不需要手動做任何事。

需要主動移除的情境主要是 Single Page Application(SPA),也就是在同一個頁面中動態新增與移除元素的情況。需要注意的是,從 DOM 中移除一個元素,不代表這個元素就被丟棄了。DOM 元素是 JavaScript 物件,可以在不顯示於畫面的狀態下繼續存在,之後還可能重新插入 DOM。

更常見的使用案例是使用者狀態的改變。例如頁面上有一個客服按鈕,當使用者登出後,這個按鈕仍然顯示在畫面上,但此時連接到使用者帳號的事件處理函式就不應該繼續存在,需要主動移除。

自訂事件與 dispatchEvent

DOM API 允許你建立並派送自訂事件,這是一個常被忽略但非常實用的功能。

javascript
const event = new Event("mycustomname");
element.dispatchEvent(event);

自訂事件的名稱是任意字串,不需要遵守 W3C 的命名規則。你可以在任何 DOM 元素、documentwindow 上派送事件,頁面上其他任何地方只要有監聽這個事件名稱,都會收到通知。

這個機制和 React 的 Context 或 Angular 的事件廣播有類似的概念:一個地方觸發,多個地方可以訂閱與回應。

自訂事件物件也可以攜帶附加的資訊(metadata),甚至可以繼承自 Event 類別建立有自己介面的自訂事件型別。這不是你「必須」使用的做法,而是 Vanilla JS 提供的一種工具,視需求選用。

多個事件監聽器的執行順序

當同一個元素、同一個事件上掛載了多個 addEventListener,它們不會平行執行,而是依序執行。這是因為 JavaScript 是單執行緒語言,所有事情都在同一條執行緒上按順序發生。如果確實需要平行處理,需要使用 Web Workers,但那需要手動建立,不會自動發生

複習

在 addEventListener 中將 once 選項設為 true 的用途是什麼?

當 once 設為 true 時,事件處理函式在第一次觸發後會自動被移除,確保該事件只會被執行一次。

在 addEventListener 中,passive 選項的作用是什麼?

passive 選項讓瀏覽器不必等待事件處理函式執行完畢就能繼續進行渲染,主要用於滾動等場景的效能優化,表示該事件處理函式不會修改 DOM。

什麼時候建議使用 removeEventListener?

在 Single Page Application 中動態新增與移除元素時,應使用 removeEventListener 來避免不再需要的事件監聽器繼續佔用記憶體。

如何在 JavaScript 中派送自訂事件?

使用自訂名稱建立新的 Event 物件,再透過 dispatchEvent 在某個元素(例如按鈕或 document)上派送,讓頁面上其他部分可以透過 DOM API 監聽並回應這個事件。

在 JavaScript 中,同一個事件上的多個事件監聽器如何執行?

由於 JavaScript 是單執行緒語言,多個事件監聽器會依照被加入的順序依序執行,不會平行發生。

小測驗

在 addEventListener 中將 once 選項設為 true 的用途是什麼? 確保事件處理函式在觸發一次後自動被移除
在新增事件監聽器時,passive 選項的作用是什麼? 告知瀏覽器可以不等待 DOM 變動,直接繼續執行渲染
什麼時候最適合使用 removeEventListener? 在動態新增與移除元素的 Single Page Application 中
在 JavaScript 中可以對自訂事件做什麼? 使用自訂名稱在 document、window 或特定元素上派送事件
同一事件上的多個事件監聽器如何被執行? 由於 JavaScript 是單執行緒的,它們會依照加入的順序依序執行

此文章是 FrontendMasters 上的 Vanilla JS: You Might Not Need a Framework 課程筆記

最後更新時間:

Buy Me A Coffee

系列章節 第 11 篇 / 共 31 篇

0 %
MIT Licensed | Copyright © 2025-present Wen-Hsiu's Blog
Photo by Federica Galli on Unsplash