JS阻止事件冒泡

在前端開發中,我們通常要處理很多與鼠標、鍵盤等用戶交互相關的事件。但是,有時候這些事件會冒泡到它們的父元素或者祖先元素中,從而影響到頁面的其他部分。幸運的是,我們可以通過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-hant/n/157618.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-11-18 20:01
下一篇 2024-11-18 20:01

相關推薦

  • JS Proxy(array)用法介紹

    JS Proxy(array)可以說是ES6中非常重要的一個特性,它可以代理一個數組,監聽數據變化並進行攔截、處理。在實際開發中,使用Proxy(array)可以方便地實現數據的監…

    編程 2025-04-29
  • 解析js base64並轉成unit

    本文將從多個方面詳細介紹js中如何解析base64編碼並轉成unit格式。 一、base64編碼解析 在JavaScript中解析base64編碼可以使用atob()函數,它會將b…

    編程 2025-04-29
  • Node.js使用Body-Parser處理HTTP POST請求時,特殊字符無法返回的解決方法

    本文將解決Node.js使用Body-Parser處理HTTP POST請求時,特殊字符無法返回的問題。同時,給出一些相關示例代碼,以幫助讀者更好的理解並處理這個問題。 一、問題解…

    編程 2025-04-29
  • t3.js:一個全能的JavaScript動態文本替換工具

    t3.js是一個非常流行的JavaScript動態文本替換工具,它是一個輕量級庫,能夠很容易地實現文本內容的遞增、遞減、替換、切換以及其他各種操作。在本文中,我們將從多個方面探討t…

    編程 2025-04-28
  • 抖音外放親媽下葬事件的背後真相

    近期,一段抖音外放親媽下葬的視頻引發廣泛關注和熱議。不少人對這個事件感到震驚和憤怒,認為這種行為非常不尊重親人,觸犯了社會公德和家庭道德。但是,事情真相到底是什麼呢?我們有必要從多…

    編程 2025-04-28
  • JS圖片沿着SVG路徑移動實現方法

    本文將為大家詳細介紹如何使用JS實現圖片沿着SVG路徑移動的效果,包括路徑製作、路徑效果、以及實現代碼等內容。 一、路徑製作 路徑的製作,我們需要使用到SVG,SVG是可縮放矢量圖…

    編程 2025-04-27
  • 如何使用JS調用Python腳本

    本文將詳細介紹通過JS調用Python腳本的方法,包括使用Node.js、Python shell、child_process等三種方法,以及在Web應用中的應用。 一、使用Nod…

    編程 2025-04-27
  • cc.director.on事件監聽器

    本文將從多個方面詳細介紹Cocos Creator中的cc.director.on事件監聽器。 一、cc.director.on的作用和用法 cc.director.on是Coco…

    編程 2025-04-27
  • 如何反混淆美團slider.js

    本文將從多個方面詳細闡述如何反混淆美團slider.js。在開始之前,需要明確的是,混淆是一種保護JavaScript代碼的方法,其目的是使代碼難以理解和修改。因此,在進行反混淆操…

    編程 2025-04-27
  • Python要學JS嗎?

    Python和JavaScript都是非常受歡迎的編程語言。然而,你可能會問,既然我已經學了Python,是不是也需要學一下JS呢?在本文中,我們將圍繞這個問題進行討論,並從多個角…

    編程 2025-04-27

發表回復

登錄後才能評論