preventDefault 的小知識

寫下來怕以後忘記。

提醒

請先理解 事件傳遞機制-捕獲與冒泡,不然保證你看不懂。

簡述

preventDefault 的作用是用來阻止元素的預設行為,但它有個特別的地方在於只要 call 了這個 function,這個效果就會按照「事件傳遞機制」來傳遞下去。

prevent-default-01

就是如果在 window 的「捕獲階段」呼叫 preventDefault,那下面的 <div><a> 也會吃到效果。

備註:

我後來發現不管 window 是在「捕獲階段」或「冒泡階段」呼叫 preventDefault<div><a> 都一樣會被影響。所以正確來說應該是「只要在同一條鏈上」,這條鏈上的所有元素都會被阻止預設行為。

實例

直接實做就比較好懂了:

1
2
3
<div>
<a href="abc.com">link</a>
</div>
1
2
3
4
// 在 window 的捕獲階段呼叫 preventDefault
window.addEventListener('click', function(e) {
e.preventDefault()
}, true)

prevent-default-02

補充-傳遞沒有分階段

把剛剛的例子改寫成這樣,效果是一樣的:

1
2
3
4
// 在 window 的冒泡階段呼叫 preventDefault
window.addEventListener('click', function(e) {
e.preventDefault()
}, false)

prevent-default-03

不管 window 是在「冒泡」或「捕獲」觸發 preventDefault,同一條事件鏈上的元素都會被影響。

只有 不在同個事件鏈上的元素 才不會被影響到,例如說:

1
2
3
4
<div class="div">
<a class="btn" href="abc.com">link</a>
<a class="btn" href="abc.com">link</a>
</div>

JavaScript:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 第一個按鈕
document.querySelectorAll('.btn')[0]
.addEventListener('click', function(e) {
// 阻止預設行為
e.preventDefault()
console.log('only I can stop!!!')
}, false)

// 第二個按鈕
document.querySelectorAll('.btn')[1]
.addEventListener('click', function(e) {
alert('oh no~')
}, false)

prevent-default-04

大概可以想成是這樣的關係:

prevent-default-05

萬事拜託你囉!Event-delegation 機制 阻止事件傳遞 stopPropagation
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×