DOM事件處理
DOM Events相關筆記
DOM事件處理
DOM(Document Object Model)
- HTML的程式介面,是網頁與使用者互動的重要部分
- 提供了文件以擁有屬性與函式的節點與物件組成的結構化表示
- 每一個節點皆為物件(Object)且擁有各自的屬性以及方法,允許在JavaScript當中操作HTML元素

事件處理
說明
- 通常是由使用者的操作行為產生(例如:滑鼠點擊、鍵盤輸入…)
- 當某個事件在某個元素上發生時,可以撰寫JS做出對應的動作
方法
- addEventListener : 新增事件監聽
- removeEventListener : 移除事件監聽
const btn = document.getElementById('myButton')
const myAlert = () => {
alert('Hello Event!')
}
// 新增事件監聽
btn.addEventListener('click', myAlert)
// 移除事件監聽
btn.removeEventListener('click', myAlert)
事件傳遞機制
事件流
- 捕獲階段(Capture Phase):
- 事件從根節點向目標元素傳播,過程中觸發個別元素的捕獲階段事件監聽
- 目標階段(Target Phase)
- 事件達到目標元素
- 冒泡階段(Bubbling Phase)
- 事件從目標元素回到根節點,過程中觸發個別元素的冒泡階段事件監聽
先捕獲,後冒泡

指定階段觸發
- 可以使用 addEventListener 的第三個參數來指定事件處理函數在哪個階段應該被觸發
- 使用 true 或 {capture: true}: 將在捕獲階段觸發
- 使用 false 或 {capture: false}: 將在冒泡階段觸發
- 不加入參數,預設為 false ,事件處理會在冒泡階段觸發
// 在冒泡階段觸發(預設)
element.addEventListener('click', function () {
console.log('Bubbling phase')
})
// 在捕獲階段觸發
element.addEventListener(
'click',
function () {
console.log('Capture phase')
},
true,
)
事件冒泡問題
- 當在冒泡階段時,事件從目標元素向上冒泡至根元素,並觸發所經過元素的事件監聽
- 過程中可能會觸發非目標元素的事件,發生非預期行為
範例
HTML結構
<div id="parent">
<button id="child">Click!</button>
</div>
JavaScript程式碼
document.getElementById('child').addEventListener('click', function () {
alert('Child Button Clicked!')
})
document.getElementById('parent').addEventListener('click', function () {
alert('Parent Div Clicked!')
})
點擊 “Click!” 按鈕時
- 先看到 “Child Button Clicked!”
- 然後會是 “Parent Div Clicked!” (不需要觸發的事件)
取消事件傳遞
event.stopPropagation()
- 阻止事件繼續冒泡或捕獲,但不會阻止同一個元素上的其他事件監聽器被觸發
<div id="parent"><button id="child">Click Me!</button></div>
// 第二個監聽器(`Second Listener: This will still fire.`)仍然會被觸發
document.getElementById('child').addEventListener('click', function (event) {
alert('First Listener: Child Button Clicked!')
event.stopPropagation()
})
document.getElementById('child').addEventListener('click', function () {
alert('Second Listener: This will still fire.')
})
document.getElementById('parent').addEventListener('click', function () {
alert('Parent Div Clicked!') // This will not be triggered
})
event.stopImmediatePropagation()
- 除了阻止事件繼續冒泡或捕獲,還會阻止同一個元素上的其他事件監聽器被觸發
//只會觸發'First Listener: Child Button Clicked!'
document.getElementById('child').addEventListener('click', function (event) {
alert('First Listener: Child Button Clicked!')
event.stopImmediatePropagation()
})
document.getElementById('child').addEventListener('click', function () {
alert('Second Listener: This will not fire.')
})
document.getElementById('parent').addEventListener('click', function () {
alert('Parent Div Clicked!') // This will not be triggered
})
事件委派 ( Event Delegation)
- 利用事件冒泡的特性,可以只新增事件監聽器到父元素,處理多個子元素的事件
- 減少監聽器數量, 讓程式碼更有效率
範例
- 使用 event.target ,可以判斷哪個子元素被點擊
document.getElementById('parent').addEventListener('click', function (event) {
if (event.target.id === 'child') {
alert('Child Button Clicked through Delegation!')
}
})