Contents

JS 原生方法做到 jQuery one 事件

jQuery 的 .one() 方法可以讓事件監聽器只觸發一次後自動解除,是很實用的功能。現代原生 JavaScript 提供了更優雅的方式來達成相同效果。

jQuery .one() 的行為

\#btn.one('click', handler) 會在第一次點擊後自動移除這個事件監聽器,後續的點擊不再觸發。等同於:

1
2
3
4
5
function handler() {
  // 執行邏輯
  this.removeEventListener('click', handler);
}
element.addEventListener('click', handler);

方法一:使用 { once: true }(推薦)

現代瀏覽器的 addEventListener 支援第三個參數傳入 options 物件,其中 once: true 可直接實現「只觸發一次」:

1
2
3
4
5
const btn = document.querySelector('#btn');

btn.addEventListener('click', () => {
  console.log('只會執行一次!');
}, { once: true });

這是最簡潔的方式,瀏覽器會在事件觸發後自動移除監聽器。

addEventListener 第三個參數的其他選項

選項 型別 說明
once Boolean true 表示只觸發一次,觸發後自動移除
passive Boolean true 表示不會呼叫 preventDefault(),可提升捲動效能
capture Boolean true 表示在捕獲階段觸發(預設 false 為冒泡階段)
signal AbortSignal 可用來取消事件監聽
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// 同時使用多個選項
element.addEventListener('scroll', onScroll, {
  passive: true,  // 告知瀏覽器不會阻止預設捲動行為,提升效能
  once: false     // 持續觸發
});

// 使用 capture 在捕獲階段監聽
document.addEventListener('click', handler, {
  capture: true,  // 在事件傳播到目標元素前就攔截
  once: true
});

方法二:手動 removeEventListener

若瀏覽器不支援 { once: true },可手動移除:

1
2
3
4
5
6
function handleClick() {
  console.log('只執行一次');
  this.removeEventListener('click', handleClick);
}

document.querySelector('#btn').addEventListener('click', handleClick);

使用箭頭函式時需要保留函式參考:

1
2
3
4
5
6
7
8
const btn = document.querySelector('#btn');

const handleClick = () => {
  console.log('只執行一次');
  btn.removeEventListener('click', handleClick);
};

btn.addEventListener('click', handleClick);

方法三:用 data 屬性記錄狀態

適合需要判斷「是否已觸發過」而非完全移除監聽的情況:

1
2
3
4
5
6
document.querySelector('#btn').addEventListener('click', function(e) {
  if (e.currentTarget.dataset.triggered) return;
  e.currentTarget.dataset.triggered = 'true';

  console.log('第一次點擊執行的邏輯');
});

瀏覽器支援度

{ once: true } 的瀏覽器支援情況:

瀏覽器 支援版本
Chrome 55+
Firefox 50+
Safari 10+
Edge 16+
IE 不支援

若需要支援 IE,使用方法二(手動 removeEventListener)或方法三(data 屬性)。

現代前端開發(2020 年以後)通常不需要支援 IE,直接使用 { once: true } 是最佳實踐。

參考資料