Skip to content

事件處理

在 JavaScript 中,事件處理是一個核心概念,它允許你對用戶在網頁上的操作作出反應。這些操作可以是點擊按鈕、移動滑鼠、按鍵盤鍵等等。通過事件處理,你可以讓你的網頁變得更加互動和動態。

以下是對 JavaScript 中事件處理的詳細說明:

1. 什麼是事件?

事件是一種用戶或瀏覽器觸發的行為,可以通過 JavaScript 來捕捉和響應。常見的事件包括:

  • click:用戶點擊元素時觸發。
  • mouseover:用戶將鼠標移到某個元素上時觸發。
  • keydown:用戶按下鍵盤鍵時觸發。
  • load:頁面或某個元素加載完成時觸發。

2. 事件處理器(Event Handler)

事件處理器是處理事件的函式。當事件發生時,事件處理器會被調用。

2.1 使用 HTML 屬性綁定事件處理器

你可以直接在 HTML 中使用屬性綁定事件處理器,例如:

<button onclick="alert('Button clicked!')">Click me</button>
當用戶點擊這個按鈕時,alert 函式會被調用。

2.2 使用 JavaScript 綁定事件處理器

更常見且推薦的方式是使用 JavaScript 綁定事件處理器。這樣可以將行為與結構分離。

let button = document.getElementById("myButton");
button.onclick = function() {
    alert("Button clicked!");
};
這種方式有利於代碼的組織和可讀性。

3. 使用 addEventListener

addEventListener 是現代且靈活的事件綁定方式,它允許你為一個元素綁定多個事件處理器,並且可以在事件的捕獲和冒泡階段觸發處理器。

3.1 基本用法

let button = document.getElementById("myButton");
button.addEventListener("click", function() {
    alert("Button clicked!");
});

3.2 移除事件處理器

你可以使用 removeEventListener 來移除之前綁定的事件處理器。為了移除事件處理器,你需要傳遞相同的函式引用。

function handleClick() {
    alert("Button clicked!");
}

button.addEventListener("click", handleClick);

// 移除事件處理器
button.removeEventListener("click", handleClick);

4. 事件對象(Event Object)

當事件觸發時,瀏覽器會創建一個事件對象並將其作為參數傳遞給事件處理器。這個對象包含了關於事件的詳細資訊,例如觸發事件的元素、鼠標位置、鍵盤按鍵等。

4.1 使用事件對象

button.addEventListener("click", function(event) {
    console.log("Clicked element:", event.target);
    console.log("Mouse X:", event.clientX);
    console.log("Mouse Y:", event.clientY);
});

在這個範例中,event.target 指向觸發事件的元素,event.clientXevent.clientY 分別表示鼠標點擊的位置。

5. 事件冒泡與捕獲

事件傳播包括三個階段:捕獲階段、目標階段、冒泡階段。

  • 捕獲階段:事件從根節點向下傳播到目標元素。
  • 目標階段:事件到達目標元素。
  • 冒泡階段:事件從目標元素向上冒泡到根節點。

默認情況下,事件處理器是在冒泡階段被觸發的,但你也可以選擇在捕獲階段觸發處理器。

5.1 事件冒泡

document.body.addEventListener("click", function() {
    console.log("Body clicked!");
});

button.addEventListener("click", function(event) {
    console.log("Button clicked!");
});

在這個範例中,如果點擊按鈕,控制台將首先打印 "Button clicked!",然後打印 "Body clicked!",因為事件會冒泡到 body

5.2 事件捕獲

你可以在捕獲階段處理事件,通過將 addEventListener 的第三個參數設置為 true

document.body.addEventListener("click", function() {
    console.log("Body clicked!");
}, true);

button.addEventListener("click", function(event) {
    console.log("Button clicked!");
}, true);

這時,如果點擊按鈕,控制台將首先打印 "Body clicked!",然後打印 "Button clicked!",因為事件在捕獲階段被處理。

5.3 停止事件冒泡

你可以使用 event.stopPropagation() 來阻止事件冒泡。

button.addEventListener("click", function(event) {
    event.stopPropagation();
    console.log("Button clicked!");
});

在這個範例中,當按鈕被點擊時,事件不會冒泡到 body,所以 "Body clicked!" 不會被打印。

6. 預設行為與 preventDefault

一些事件會觸發預設行為,例如提交表單時的頁面重新加載、點擊鏈接時的導航等。你可以使用 event.preventDefault() 來阻止這些預設行為。

6.1 阻止鏈接的導航

let link = document.getElementById("myLink");
link.addEventListener("click", function(event) {
    event.preventDefault();
    console.log("Link click prevented!");
});

這樣,點擊該鏈接時,瀏覽器不會導航到鏈接指向的 URL。

6.2 阻止表單提交

let form = document.getElementById("myForm");
form.addEventListener("submit", function(event) {
    event.preventDefault();
    console.log("Form submission prevented!");
});

7. 事件委託

事件委託是一種技術,通過利用事件冒泡,你可以在父元素上監聽事件,從而避免在多個子元素上添加事件處理器。

7.1 範例

假設你有一個包含多個按鈕的列表,與其為每個按鈕添加事件處理器,不如將事件處理器添加到父元素上:

let list = document.getElementById("myList");

list.addEventListener("click", function(event) {
    if (event.target.tagName === "BUTTON") {
        console.log("Button clicked:", event.target.textContent);
    }
});
這樣,當任何一個按鈕被點擊時,事件處理器都會被觸發,而你只需要在父元素上綁定一次事件處理器。

8. 常見事件類型

以下是一些常見的事件類型及其使用範例:

  • click:點擊事件。

    button.addEventListener("click", function() {
        console.log("Button clicked!");
    });
    

  • dblclick:雙擊事件。

    button.addEventListener("dblclick", function() {
        console.log("Button double-clicked!");
    });
    

  • mouseovermouseout:鼠標移入和移出事件。

    button.addEventListener("mouseover", function() {
        console.log("Mouse over button!");
    });
    
    button.addEventListener("mouseout", function() {
        console.log("Mouse out of button!");
    });
    

  • keydownkeyup:鍵盤按鍵按下和鬆開事件。

    document.addEventListener("keydown", function(event) {
        console.log("Key down:", event.key);
    });
    
    document.addEventListener("keyup", function(event) {
        console.log("Key up:", event.key);
    });
    

  • focusblur:元素獲得和失去焦點事件。

    let input = document.getElementById("myInput");
    
    input.addEventListener("focus", function() {
        console.log("Input focused!");
    });
    
    input.addEventListener("blur", function() {
        console.log("Input blurred!");
    });
    

9. 事件處理最佳實踐

  • 使用 addEventListener 而不是內聯事件處理器:這樣可以保持 HTML 的整潔並使代碼更具可維護性。
  • 避免使用匿名函式:使用命名函式更容易移除事件處理器並使代碼可讀性更好。
  • 善用事件委託:特別是在處理大量類似元素的事件時,事件委託可以提高性能並簡化代碼。

總結來說,掌握事件處理是學習 JavaScript 的關鍵,它允許你創建更加互動和動態的網頁。隨著經驗的積累,你會發現事件處理是許多複雜功能的基礎。