7) 鍵盤與可近用性(A11y)
元素不只要能 click,也要能用鍵盤操作(Enter / Space)。
使用 role="button" + tabindex="0" + keydown 支援鍵盤互動,對鍵盤使用者與助讀器很重要。
<div role="button" tabindex="0" id="toggle">切換</div>
<script>
const t = document.getElementById('toggle');
t.addEventListener('keydown', (e) => {
if (e.key === 'Enter' || e.key === ' ') { t.click(); } // 觸發同樣行為
});
</script>
8) Mouse / Touch / Pointer 事件怎麼選?
👉 建議:若要同時支援多裝置,用 Pointer Events(較現代、覆蓋面廣)。
elem.addEventListener('pointerdown', onDown);
9) 效能:Debounce / Throttle(高頻事件必備)
簡易 debounce:
function debounce(fn, delay=300){
let t;
return (...args) => {
clearTimeout(t);
t = setTimeout(() => fn.apply(this, args), delay);
};
}
window.addEventListener('resize', debounce(() => {
console.log('resized!');
}, 200));
10) 移除監聽與避免記憶體洩漏
需要時用 removeEventListener 拆掉監聽(回調與 options 必須同一個參考)。
或一開始就用 { once: true }。
長列表、SPA 路由切換、關閉 modal 時特別要注意解除監聽。
function onScroll(){ /* ... */ }
window.addEventListener('scroll', onScroll, { passive: true });
// ...不需要時
window.removeEventListener('scroll', onScroll, { passive: true });
11) this 與箭頭函式
在事件 handler(一般函式)中,this 預設指向 currentTarget。
箭頭函式沒有自己的 this,會用外層 this(常見在 class/模組裡避免 this 綁定混亂)。
一般前端日常用箭頭函式較直覺;若需依賴 this,可以用傳統函式或 bind。
btn.addEventListener('click', function(){ console.log(this); }); // btn
btn.addEventListener('click', () => { console.log(this); }); // 外層 this
12) 自訂事件與跨元件通訊
可以用 CustomEvent 自己定義事件,並帶資料 detail,在元件之間傳遞訊息很方便。
const card = document.getElementById('card');
card.addEventListener('favor', (e) => {
console.log('被收藏了', e.detail.id);
});
card.dispatchEvent(new CustomEvent('favor', { detail: { id: 42 } }));
13) 實用小模式彙整
<ul id="menu">
<li data-action="open">開啟</li>
<li data-action="save">儲存</li>
</ul>
<script>
menu.addEventListener('click', (e) => {
const act = e.target.dataset.action;
if (!act) return;
if (act === 'open') openFile();
if (act === 'save') saveFile();
});
</script>