☕ NEW! 完成新手任務即可參加抽獎!LINE 星巴克禮券等你拿,名額有限!        🎉 推廣活動:邀請好友註冊 DevLearn,累積推薦抽 LINE 星巴克禮券! 活動詳情 →        🔥 活動期間 2026/4/1 - 5/31 |已有 0 人參加       
javascript 初學

事件處理(Event)

什麼是事件?

比喻:事件就像門鈴 🔔

有人按門鈴(事件發生)→ 你去開門(事件處理函數)。 使用者的每個動作(點擊、輸入、滾動)都是一個事件。


綁定事件

let btn = document.querySelector("#myBtn");

// 方式 1:addEventListener(推薦)
btn.addEventListener("click", function() {
    console.log("按鈕被點擊了!");
});

// 方式 2:addEventListener + 箭頭函式
btn.addEventListener("click", () => {
    console.log("按鈕被點擊了!");
});

// 方式 3:用具名函式(方便移除)
function handleClick() {
    console.log("按鈕被點擊了!");
}
btn.addEventListener("click", handleClick);
btn.removeEventListener("click", handleClick);  // ← 移除事件

事件物件(Event Object)

btn.addEventListener("click", function(event) {  // ← event 是事件物件
    console.log(event.type);          // ← "click"(事件類型)
    console.log(event.target);        // ← 被點擊的元素
    console.log(event.clientX);       // ← 滑鼠 X 座標
    console.log(event.clientY);       // ← 滑鼠 Y 座標
    event.preventDefault();           // ← 阻止預設行為(如表單送出)
    event.stopPropagation();          // ← 阻止事件冒泡
});

常見事件類型

滑鼠事件

el.addEventListener("click", handler);        // 單擊
el.addEventListener("dblclick", handler);      // 雙擊
el.addEventListener("mouseenter", handler);    // 滑鼠移入
el.addEventListener("mouseleave", handler);    // 滑鼠移出
el.addEventListener("mousemove", handler);     // 滑鼠移動

鍵盤事件

document.addEventListener("keydown", (e) => {
    console.log(e.key);              // ← 按了什麼鍵("Enter"、"a"、"Escape")
    console.log(e.code);             // ← 鍵碼("KeyA"、"ArrowUp")
    console.log(e.ctrlKey);          // ← 是否按住 Ctrl
    console.log(e.shiftKey);         // ← 是否按住 Shift
});

表單事件

let input = document.querySelector("input");
let form = document.querySelector("form");

input.addEventListener("input", (e) => {      // ← 每次輸入都觸發
    console.log(e.target.value);
});

input.addEventListener("change", (e) => {     // ← 失去焦點時觸發
    console.log(e.target.value);
});

form.addEventListener("submit", (e) => {
    e.preventDefault();                         // ← 阻止表單送出(自己處理)
    let formData = new FormData(form);
    console.log(formData.get("username"));
});

事件委派(Event Delegation)

// ❌ 壞:對每個 li 都綁事件
document.querySelectorAll("li").forEach(li => {
    li.addEventListener("click", () => { /* ... */ });
});
// 問題:如果動態新增 li,新的 li 不會有事件

// ✅ 好:在父元素上用事件委派
document.querySelector("ul").addEventListener("click", (e) => {
    if (e.target.tagName === "LI") {     // ← 檢查是不是 li 被點
        console.log(e.target.textContent);
    }
});
// 優點:動態新增的 li 也能觸發!

逐行解析:

ul.addEventListener("click", ...)   -- 事件綁在父元素 ul 上
e.target                            -- 實際被點擊的元素(可能是 li、span 等)
e.target.tagName === "LI"           -- 確認是 li 被點才處理
e.currentTarget                     -- 綁定事件的元素(ul)

防抖與節流

// 防抖(Debounce)— 停止操作後才執行
function debounce(fn, delay) {
    let timer;
    return function(...args) {
        clearTimeout(timer);
        timer = setTimeout(() => fn.apply(this, args), delay);
    };
}

// 使用:搜尋框輸入 300ms 後才發送請求
let searchInput = document.querySelector("#search");
searchInput.addEventListener("input", debounce((e) => {
    fetch(`/api/search?q=${e.target.value}`);
}, 300));

// 節流(Throttle)— 固定間隔執行一次
function throttle(fn, limit) {
    let inThrottle;
    return function(...args) {
        if (!inThrottle) {
            fn.apply(this, args);
            inThrottle = true;
            setTimeout(() => inThrottle = false, limit);
        }
    };
}

// 使用:滾動事件每 100ms 最多觸發一次
window.addEventListener("scroll", throttle(() => {
    console.log("滾動中...");
}, 100));

💡 大家的想法 · 0

載入中...
💬 即時聊天室 🟢 0 人在線
😀 😎 🤓 💻 🎮 🎸 🔥
➕ 新問題
📋 我的工單
💬 LINE 社群
🔒
需要註冊才能使用此功能
註冊帳號即可解鎖測驗、遊戲、簽到、筆記下載等所有功能,完全免費!
免費註冊