在前端開發中,我們通常要處理很多與鼠標、鍵盤等用戶交互相關的事件。但是,有時候這些事件會冒泡到它們的父元素或者祖先元素中,從而影響到頁面的其他部分。幸運的是,我們可以通過JS阻止事件冒泡來避免這種情況發生。本文將會從多個方面詳細介紹JS阻止事件冒泡的方法和應用場景。
一、JS阻止事件冒泡的方法
在介紹具體的JS阻止事件冒泡方法之前,我們先來了解一下事件冒泡的概念。當鼠標在某個元素上觸發一個事件時,這個事件會向該元素的父級元素冒泡,直到冒泡到document對象為止。下面是JS阻止事件冒泡的幾種常見方法:
1. stopPropagation()
使用stopPropagation()方法可以阻止事件冒泡。這個方法是事件對象的一個方法,用來停止事件傳播,防止觸發父級元素的同名事件。具體的調用方式如下:
document.querySelector('#child').addEventListener('click', function(event) {
event.stopPropagation();
console.log('child clicked');
});
上面的代碼中,當鼠標在id為child的元素上點擊時,click事件不會向其父元素冒泡,因為我們使用了stopPropagation()方法阻止了事件的傳播。因此,當我們在child元素上點擊時,控制台只會輸出’child clicked’,而不會輸出’parent clicked’。
2. stopImmediatePropagation()
有時候一個元素上會同時綁定多個事件處理函數,如果你想阻止所有的事件冒泡並且阻止該元素上的所有其他事件處理函數的執行,可以使用stopImmediatePropagation()方法。它的調用方式和stopPropagation()類似,只不過它可以防止元素上其他的事件處理函數執行。下面是一個使用stopImmediatePropagation()方法的例子:
document.querySelector('#child').addEventListener('click', function(event) {
event.stopImmediatePropagation();
console.log('child clicked');
});
document.querySelector('#child').addEventListener('click', function(event) {
console.log('child clicked again');
});
上面的代碼中,當我們在id為child的元素上點擊時,事件不僅不會向其父元素冒泡,而且不會執行child元素上其他的事件處理函數。當我們點擊元素時,在控制台中只會輸出’child clicked’,不會輸出’child clicked again’。
3. addEventListener(options)
在addEventListener的第二個參數中,你可以傳遞一個options對象來指定事件處理函數的行為。其中的passive屬性可以設置為true來防止事件傳播。這個方法是比較新的方法,在較老的瀏覽器中可能不支持。下面是一個使用addEventListener()的例子:
document.querySelector('#child').addEventListener('click', function(event) {
console.log('child clicked');
}, { passive: true });
需要注意的是,在某些高頻事件(例如touchmove等)中使用passive可以提高性能。
二、JS阻止冒泡和默認事件
在前端開發中,有時候我們需要同時阻止事件冒泡和默認事件的執行。默認事件是指瀏覽器對某些事件的默認行為的處理方式,例如當我們在一個鏈接上點擊時,瀏覽器默認會打開鏈接地址。下面是一種同時阻止事件冒泡和默認事件的方法:
document.querySelector('#child').addEventListener('click', function(event) {
event.preventDefault();
event.stopPropagation();
console.log('child clicked');
});
在這個例子中,我們使用event.preventDefault()來阻止默認事件,使用event.stopPropagation()來阻止事件冒泡。這樣就可以在不影響元素的默認行為的情況下阻止事件冒泡了。
三、JS阻止冒泡和捕獲
在事件傳播過程中,從最外層的元素往目標元素方向傳播的過程稱為事件捕獲,而從目標元素往最外層元素方向傳播的過程稱為事件冒泡。默認情況下,addEventListener()方法被調用時,第三個參數useCapture默認為false,即默認使用事件冒泡。我們可以把該參數設置為true來使用事件捕獲。下面是使用事件捕獲和阻止事件冒泡的例子:
document.querySelector('html').addEventListener("click", function(event) {
console.log("html clicked");
}, true);
document.querySelector('body').addEventListener("click", function(event) {
event.stopPropagation();
console.log("body clicked");
}, true);
document.querySelector('#child').addEventListener("click", function(event) {
console.log("child clicked");
}, true);
在這個例子中,我們可以看到當鼠標點擊child元素時,事件會從最外層的html元素被捕獲,向下傳遞到了body元素,接着到了child元素,而且click事件也不會繼續往上傳到body和html元素。這是因為我們在body元素上調用了event.stopPropagation()方法。而當我們在body或者html上點擊時,它們的點擊事件不會冒泡給child元素。
四、JS阻止事件冒泡的兩種方法
除了上面提到的stopPropagation()和stopImmediatePropagation()之外,還有兩種阻止事件冒泡的方法:
1. return false
在事件處理函數中使用return false可以阻止事件冒泡。例如:
document.querySelector('#child').addEventListener('click', function(event) {
console.log('child clicked');
return false;
});
在這個例子中,當我們在child元素上點擊時,事件不會冒泡給parent元素了,因為我們在事件處理函數中返回了false。需要注意的是,return false不僅會阻止事件冒泡,還會阻止默認事件的執行。
2. onclick
可以在HTML中使用onclick屬性來指定元素被點擊時的處理函數,並且使用return false來阻止事件冒泡和默認事件。例如:
<div id="child" onclick="console.log('child clicked'); return false;">child</div>
在這個例子中,當我們在child元素上點擊時,事件不會向其父元素冒泡,而且也不會執行瀏覽器默認的行為。
五、原生JS阻止事件冒泡的方法
在原生的JS中,我們也可以使用return false或者event.stopPropagation()來阻止事件冒泡。例如:
document.getElementById('child').onclick = function(event) {
console.log('child clicked');
return false;
};
需要注意的是,當我們使用原生的JS時,請勿在事件處理函數中使用return false和調用event.preventDefault(),因為這會導致一些錯誤,例如IE瀏覽器中會出現無法禁用鏈接的情況。
六、JS阻止事件冒泡不起作用
有時候,阻止事件冒泡的方法並不起作用,這可能是由於事件處理函數的執行時間較長,導致無法成功阻止事件冒泡。這時候我們可以使用setTimeout()函數來解決這個問題。例如:
document.querySelector('#child').addEventListener('click', function(event) {
setTimeout(function() {
event.stopPropagation();
console.log('child clicked');
}, 100);
});
在這個例子中,我們使用了setTimeout()函數來延遲事件處理函數的執行時間,使事件能夠成功地被阻止冒泡。
七、Vue阻止事件冒泡
在Vue中,可以使用.stop修飾符來阻止事件冒泡。例如:
<div id="child" @click.stop="handler">child</div>
在這個例子中,我們使用@click事件監聽給child元素綁定了一個事件處理函數handler,並使用.stop修飾符阻止了事件冒泡。也可以使用@mousedown.stop等事件在Vue中阻止事件冒泡。
八、CSS阻止事件冒泡
在CSS中,可以使用pointer-events屬性阻止事件往下傳遞。例如:
#child {
pointer-events: none;
}
在這個例子中,我們使用pointer-events: none來阻止了child元素上的所有事件(包括鼠標和鍵盤事件)。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/157618.html