逛帖子的時候看到道友發的前端面試題,
preventDefault(), stopPropagation(), return false三者的區別
這三者的使用想必大家並不陌生,但是細想之下還是有可究之處。
preventDefault()
阻止元素在瀏覽器中的預設行為
<a id="link" href="http://wuliv.com">網站</a>
$(`#link`).click(function(event){
event.preventDefault(); // 阻止了a連結href的訪問或跳轉
})
stopPropagation()
事件冒泡:當一個元素上的事件被觸發時,比如滑鼠點選了一個按鈕,同樣的事件將會在該按鈕元素的所有父級/祖先元素上觸發。這一個過程就被稱為事件冒泡。它是由子級元素先觸發,父級元素後觸發,由內而外(由下往上)的一個流程。與之順序相反的是事件捕獲。
事件捕獲:父級元素先觸發,子級元素後觸發,在此僅做了解。
<body>
<div id="inner">
<p>事件冒泡例子</p>
<button id="btn">我要彈個框</button>
</div>
</div>
$(`#btn`).click(function(event){
event.stopPropagation(); // 阻止了事件冒泡,不會觸發"#inner, body"的點選事件
console.log(`#btn`)
})
$(`#inner`).click(function(event){
// #btn 阻止了冒泡,這裡不會執行
// 如果不使用stopPropagation, 當#btn點選時,這裡也會執行
console.log(`#inner`)
})
$(`body`).click(function(event){
// #btn 阻止了冒泡,.btn點選不會影響到我
// 如果不使用stopPropagation, 當#btn點選時,這裡也會執行
console.log(`body`)
})
// 使用了stopPropagation()輸出
`#btn`
// 不使用stopPropagation()輸出
`#btn`
`#inner`
`body`
stopImmediatePropagation()
阻止物件繫結的剩餘的事件處理函式方法的執行,並阻止當前事件的冒泡。
可以理解為stopImmediatePropagation是stopPropagation的升級版,除了阻止冒泡,還能阻止結束掉當前物件未執行的其它繫結事件方法。
jQuery中一個物件可以繫結多個事件方法,執行順序會按照繫結的先後順序來執行
<body>
<div id="inner">
<p>stopImmediatePropagation()例子</p>
<button id="btn">按鈕</btn>
</div>
</body>
$(`body`).click(function(event){
// body 點選
console.log(`body`);
});
$(`#inner`).click(function(event){
// #inner 點選
console.log(`#inner`);
})
$(`#btn`).click(function(event){
// 第一個#btn點選
e.stopImmediatePropagation();
console.log(`#btn 1`);
})
$(`#btn`).click(function(event){
// 第二個#btn點選
console.log(`#btn 2`)
})
// 最終輸出
`#btn 1` // (因為stopImmediatePropagation阻止了#btn繫結的剩餘未執行的事件方法,並且阻止了冒泡)
// 如果不使用stopImmediatePropagation, 將輸出
`#btn 1`
`#btn 2`
`#inner`
`body`
同個物件執行順序按繫結順序執行,冒泡則由內向外執行
return false
“return false” 相信不少同學會用來阻止元素在瀏覽器中的預設行為,
拿它當preventDefault()使用,但其實“return false”做的事情不僅僅只是阻止預設行為
當呼叫“return false”時,它執行了以下三件事情
event.preventDefault()
event.stopPropagation()
停止回撥函式執行並立即返回
1,2點還好理解,那麼第3點是怎麼回事?
return語句會終止函式的執行並返回函式的值。所以不管是否返回false或是其它值,return語句後面的程式碼都不會執行。而返回false,使它具備了preventDefault和stropPropagation的功能
$(`a`).click(function(){
return false; // return false直接返回了,並不會執行alert
alert(`我沒有被彈出來`);
})
// preventDefault 和 stopPropagation 並不會阻止回撥函式的執行
總結
很多jQuery教程在程式碼演示中用“return false”來阻止執行瀏覽器的預設行為。
久而久之,很多同學習慣濫用“return false”來代替preventDefault
大多數情況下,我們僅僅是想要它執行跟preventDefault的功能而已,但它卻自作主張地幫你執行了另外兩步操作。
比較好的程式設計習慣是,需要用到該事件方法再去呼叫,否則應該避免冗餘事件的執行。
就像prevnetDefault完成它該有的工作,並不會阻止父節點繼續處理事件,使得程式碼更加靈活,更易於維護。
日常開發中還是要慎用“return false”,除非你同時需要preventDefault和stopPropagation,並且確定你的回撥函式執行完成後呼叫,那麼你可以使用“return false”,否則還是用preventDefault 或 stopPropagation 更好些。
作者:以樂之名
本文原創,有不當的地方歡迎指出。轉載請指明出處。
參考文章:《preventDefault()、stopPropagation()、return false 之間的區別》