事件處理是讓網頁變得互動的重要機制,透過 JavaScript可以監聽使用者的動作(如點擊、滑鼠移動、鍵盤輸入等),並根據這些操作做出回應。同時,我們也會討論事件冒泡與捕獲的機制,並介紹事件代理技術來提升事件處理的效率。
1.事件處理(Event Handling)
事件處理的基本方式是將一個「事件監聽器」綁定到 HTML 元素,當指定的事件發生時,JavaScript 會觸發相應的函數來做出回應。
addEventListener():允許你為一個元素註冊多個事件,並且不會覆蓋之前的事件。它是處理事件的標準方法。
let button = document.querySelector("button");
button.addEventListener("click", function() {
console.log("按鈕被點擊了!");
});
常見事件類型
JavaScript 支援多種事件類型,以下是一些常見的事件:
click:當使用者點擊元素時觸發。
mouseover:當滑鼠移動到元素上時觸發。
keydown:當使用者按下鍵盤按鍵時觸發。
2.事件冒泡與事件捕獲
在網頁中,事件的處理順序非常重要,尤其是當事件發生在多層嵌套的元素上時。這涉及到兩個概念:事件冒泡(Event Bubbling)和事件捕獲(Event Capturing)。
事件冒泡
當一個事件發生時,會從最內層的元素開始觸發,然後向外逐層傳播,直到最外層的祖先元素。這個過程稱為「冒泡」。
<div id="container">
<button id="btn">點擊我</button>
</div>
let container = document.getElementById("container");
let button = document.getElementById("btn");
container.addEventListener("click", function() {
console.log("容器被點擊了!");
});
button.addEventListener("click", function() {
console.log("按鈕被點擊了!");
});
當點擊按鈕時,控制台會依次顯示「按鈕被點擊了!」和「容器被點擊了!」,因為事件從按鈕冒泡到容器。
事件捕獲
事件捕獲與冒泡相反,事件會從最外層的祖先元素開始,向內層傳遞到目標元素。
container.addEventListener("click", function() {
console.log("容器捕獲到點擊事件");
}, true);
button.addEventListener("click", function() {
console.log("按鈕捕獲到點擊事件");
}, true);
這樣,當你點擊按鈕時,容器會先捕獲到事件,然後才是按鈕。
停止事件傳播
有時候,我們不希望事件從某個元素繼續冒泡或捕獲。這時可以使用 stopPropagation()方法來停止事件的傳播。
button.addEventListener("click", function(event) {
event.stopPropagation(); // 阻止事件冒泡
console.log("按鈕被點擊了,但不會冒泡到容器");
});
當 stopPropagation() 被調用後,點擊按鈕不會再觸發容器的 click 事件。
3. 事件代理 (Event Delegation)
事件代理是一種高效的事件處理方式,適用於當我們需要監聽大量相似元素的事件時。這種技術的核心思想是,不為每個子元素單獨添加事件監聽器,而是將事件監聽器添加到共同的父元素上,並利用事件冒泡來處理子元素的事件。
假設我們有一個清單,清單中的項目可以動態新增或刪除。我們可以為整個清單添加一個事件監聽器,而不是為每個清單項目分別添加。
<ul id="list">
<li>項目 1</li>
<li>項目 2</li>
<li>項目 3</li>
</ul>
let list = document.getElementById("list");
list.addEventListener("click", function(event) {
if (event.target && event.target.nodeName === "LI") {
console.log("點擊了: " + event.target.textContent);
}
});
在這個範例中,我們為 ul 標籤(清單的父元素)添加了 click 事件監聽器。當清單中的 li 被點擊時,事件會冒泡到 ul,並在父元素上處理點擊事件。
這樣,即使後續動態新增新的清單項目,我們也不需要再為每個 li 單獨添加事件監聽器,因為父元素已經負責處理所有的子元素事件了。