如何阻止冒泡&&瀏覽器默認行為


摘要

很多同學對阻止事件冒泡和阻止事件默認行為容易混淆,項目中因為一些原因也需要阻止瀏覽器的一些默認行為,這里就簡單總結一下。

阻止事件冒泡

什么是事件冒泡這里就不再贅述了,網上的文章一大把,這里就簡述一下如何阻止事件冒泡,阻止事件冒泡在使用瀏覽器原生API的情況下,是需要分情況考慮的,畢竟有個個性的瀏覽器IE,這里分為IE實現和W3C標准實現。
在W3C標准實現中,我們阻止事件冒泡可以很容易使用標准API
基本語法:

event.stopPropagation();

IE實現下(這里主要指IE低版本IE9以下版本,因為IE9也實現了W3C標准)
基本語法:

event.cancelBubble = bool;

當然IE標准並不是只有IE支持,其實很多瀏覽器都實現了cancelBubble支持,但是后來雖然瀏覽器沒有取消對cancelBubble屬性的支持,設置了之后也會無效,所以建議的兼容語法是:

function eventCallback(e){
    e = e||window.event;
    if(e.stopPropagation){ //通過瀏覽器能力進行兼容性檢測
        e.stopPropagation(); 
    }else if(e.cancelBubble){
        e.cancelBubble = true;
    }
}

當然說到阻止事件冒泡這個問題,也要簡單提一下 event.stopPropagation 和event.stopImmediatePropagation的異同點:

  • 相同點是兩者都能阻止標准事件注冊方式注冊的事件 (addEventListener,IE是attachEvent)向父級節點繼續冒泡
  • 不同點從名字上可以看出,Immediate立即的意思,event.stopImmediatePropagation 不止能阻止往父級節點冒泡,還能阻止當前節點其它事件的繼續執行(比如往一個元素上注冊了多個事件,那么在第一個事件執行的時候,通過調用event.stopImmediatePropagation,會阻止其它事件的執行)

上面代碼需要注意的一點是,IE下e不存在,從window中獲取,簡單做了兼容處理。可以嘗試使用return false

阻止瀏覽器默認行為

在開始之前,首先需要了解什么是瀏覽器的默認行為,我這里簡單舉幾個例子:

  1. 點擊a標簽,如果設置了href會執行跳轉
  2. 點擊輸入框,輸入框會獲取焦點
  3. 點擊右鍵,會彈出瀏覽器右鍵菜單
  4. 點擊submit,會提交其所在表單
  5. 點擊checkbox 會選中或者反選

還有其他的很多,這里就不一一列舉了

同樣的對於阻止瀏覽器默認行為的實現也分為W3C標准實現和IE實現(這里也只是指IE9以下的實現)

在W3C標准實現中,其基本語法如下:

event.preventDefault();

在IE實現中,其基本語法如下:

window.event.returnValue = false;

所以其兼容版本偽代碼如下


function eventCallback(e){
    e = e || window.event;
    if(e.preventDefault){
        e.preventDefault()
    }else {
        e.returnValue = false;
    }
}

這里簡單那checkbox做一個小的demo:

<!DOCTYPE>
<html>
    <head>
        <title>preventDefault Demo</title>
    </head>
    <body>
        <h1>Please click on the checkbox</h1>
        <form>
            <label for="chk_just_for_test">Checkbox:</label>
            <input type="checkbox" id="chk_just_for_test"/>
        </form>
        <script>
            let chk = document.querySelector('#chk_just_for_test');
            chk.addEventListener('click',e=>{
                console.log('sorry ,do not let you check this checkbox');
                e.preventDefault(); // 這里不考慮IE低版本兼容性問題 
            })
        </script>
    </body>
</html>

有興趣的其它場景都可以寫個小demo 玩玩。

同樣W3C標准實現中,我們可以通過event.defaultPrevented 來確定event.preventDefault方法是否被調用,基本模式如下:

if (e.defaultPrevented) {
   /* the default was prevented */
 }

當然不是所有的事件都可以被cancel,瀏覽器也提供了cancelable屬性來判斷事件是否可以被取消,如果cancelable為false,那么便無法阻止瀏覽器的默認行為,如果在一個不可撤銷的事件上調用preventDefault,會拋出錯誤,所以建議在調用之前判斷事件是否可被取消.

下面是一個來自於mdn的例子,有興趣的可以直接看原文

https://developer.mozilla.org/en-US/docs/Web/API/Event/cancelable

瀏覽器廠商提議滾輪事件只有第一次可被取消

function preventScrollWheel(event) {
  if (typeof event.cancelable !== 'boolean' || event.cancelable) {
    // The event can be canceled, so we do so.
    event.preventDefault();
  } else {
    // The event cannot be canceled, so it is not safe
    // to call preventDefault() on it.
    console.warn(`The following event couldn't be canceled:`);
    console.dir(event);
  }
}

document.addEventListener('wheel', preventCancelableEvents);

總結

阻止默認冒泡和阻止瀏覽器默認行為需要關注的是兼容性問題,其它內容大家只需要關注mdn,已經很詳細的列出了兼容問題,對前端&node有興趣的歡迎微信交流,如果你能看到彈框彈出微信二維碼的話😁。

附錄

每個API的瀏覽器兼容情況如下:
event.stopPropagation

event.stopImmediatePropagation

window.event.returnValue

event.preventDefault

event.cancelable

event.cancelBubble


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM