1. 程式人生 > 其它 >冒泡與捕獲

冒泡與捕獲

點選div

點選button

 <div>
        <button>按鈕</button>
  </div>
 document.body.addEventListener('click', (e) => {
            console.log("捕獲階段body")
        }, true)
        document.getElementsByTagName('div')[0].addEventListener('click', (e) => {
            console.log('捕獲階段div')
        }, true)
        document.getElementsByTagName('button')[0].addEventListener('click', (e) => {
            console.log('捕獲階段button')
        }, true)
        document.getElementsByTagName('button')[0].addEventListener('click', (e) => {
            console.log('冒泡階段button')
        }, false)
        document.getElementsByTagName('div')[0].addEventListener('click', (e) => {
            console.log('冒泡階段div')
        }, false)
        document.body.addEventListener('click', (e) => {
            console.log("冒泡階段body"), false
        })


總結:

​ 事件捕獲 網景公司 body=》div=>button 更符合計算機的處理流程,內座標需要window外網傳過來相關座標引數

​ 事件冒泡 ie公司 button=>div=>body 更符合人類實際認知模式,由具體到上層,像金魚吐泡泡

​ W3C現在的dom流把兩種結合了規定了最新的事件流程,先從外到內(捕獲)到目標 再從內到外(冒泡)

注意:如果不註冊每個事件流階段的相應的回撥函式,整個事件流的程序並不受影響,不影響事件流的傳播,只是不會執行相應的回撥函式(比如少了列印的),但是整個事件流還是正常進行的。整個事件流的傳播不影響,只是你不註冊相應的回撥就不會列印 和vue的生命週期函式一樣

addEventListener() (預設捕獲)的第三個引數,true 表示在捕獲階段註冊,預設false 表示在冒泡階段註冊

onclick預設冒泡,谷歌瀏覽器

ie8只有冒泡,現代的瀏覽器是完整的,標準事件流

阻止冒泡事件:

一般:event.stopPropagation()

ie8: window.event.cancelBubble = true;

function stopBubble(e) {
    // 如果提供了事件物件,則這是一個非IE瀏覽器
    if ( e && e.stopPropagation ) {
        // 因此它支援W3C的stopPropagation()方法 
        e.stopPropagation();
    } else { 
        // 否則,我們需要使用IE的方式來取消事件冒泡
        window.event.cancelBubble = true;
    }
}

阻止預設事件

一般: e.preventDefault();

ie8: window.event.returnValue = false;

<a href="www.baidu.com" οnclick="clicked()">點選我並不會跳轉</a>
<script>
function stopDefault( e ) {
     // 阻止預設瀏覽器動作(W3C)
     if ( e && e.preventDefault ) {
         e.preventDefault();
     } else {
        // IE中阻止函式器預設動作的方式
        window.event.returnValue = false;
    }
    return false;
}
function clicked(event) {
    stopDefault(event);
    alert("我阻止了點選A標籤的預設事件");
}
</script>

HTML DOM addEventListener() 方法

addEventListener() 方法用於向指定元素新增事件控制代碼。

element.addEventListener(event, function, useCapture)**

引數值

引數 描述
event 必須。字串,指定事件名。 注意: 不要使用 "on" 字首。 例如,使用 "click" ,而不是使用 "onclick"。 提示: 所有 HTML DOM 事件,可以檢視我們完整的 HTML DOM Event 物件參考手冊
function 必須。指定要事件觸發時執行的函式。 當事件物件會作為第一個引數傳入函式。 事件物件的型別取決於特定的事件。例如, "click" 事件屬於 MouseEvent(滑鼠事件) 物件。
useCapture 可選。布林值,指定事件是否在捕獲或冒泡階段執行。 可能值:true - 事件控制代碼在捕獲階段執行false- false- 預設。事件控制代碼在冒泡階段執行

相容

Internet Explorer 8 及更早IE版本不支援 addEventListener() 方法,,Opera 7.0 及 Opera 更早版本也不支援

使用 attachEvent() 方法來新增事件控制代碼 :

var x = document.getElementById("myBtn");
if (x.addEventListener) {                    //所有主流瀏覽器,除了 IE 8 及更早 IE版本
    x.addEventListener("click", myFunction);
} else if (x.attachEvent) {                  // IE 8 及更早 IE 版本
    x.attachEvent("onclick", myFunction);
}

HTML DOM removeEventListener() 方法

提示: 使用 removeEventListener() 方法來移除 addEventListener() 方法新增的事件控制代碼。

如果要移除事件控制代碼,addEventListener() 的執行函式必須使用外部函式,如上例項所示 (myFunction)。

匿名函式,類似 "document.removeEventListener("event", function(){ myScript });" 該事件是無法移除的。

removeEventListener()

element.removeEventListener(event, function, useCapture)

引數值

Parameter Description
event 必須。要移除的事件名稱。. 注意:不要使用 "on" 字首。 例如,使用 "click" ,而不是使用 "onclick"。 提示: 所有 HTML DOM 事件,可以檢視我們完整的 HTML DOM Event 物件參考手冊
function 必須。指定要移除的函式。
useCapture 可選。布林值,指定移除事件控制代碼的階段。 可能值:true - 在捕獲階段移除事件控制代碼false- 預設。在冒泡階段移除事件控制代碼注意: 如果新增兩次事件控制代碼,一次在捕獲階段,一次在冒泡階段,你必須單獨移除該事件。

相容性:

var x = document.getElementById("myDIV");
if (x.removeEventListener) {                   // // 所有瀏覽器,除了 IE 8 及更早IE版本
    x.removeEventListener("mousemove", myFunction);
} else if (x.detachEvent) {                   // IE 8 及更早IE版本
    x.detachEvent("onmousemove", myFunction);
}
element.addEventListener(event, function, useCapture)

//第一個引數是需要繫結的事件
//第二個引數是觸發事件後要執行的函式
//第三個引數預設值是false,表示在事件冒泡階段呼叫事件處理函式;如果引數為true,則表示在事件捕獲階段呼叫處理函式。

react要在捕獲階段觸發某個事件處理器,在事件名字後面追加 Capture 字串;例如,使用 onClickCapture 而不是 onClick 來在捕獲階段處理點選事件

[事件系統 | React (jb51.net)](