事件冒泡和事件捕獲


 

事件冒泡

    事件冒泡是由IE開發團隊提出來的,即事件開始時由最具體的元素(文檔中嵌套層次最深的那個節點)接收,然后逐級向上傳播。

    當用戶點擊了<div>元素,click事件將按照<div>—><body>—><html>—>document的順序進行傳播。若在<div>和<body>上都定義了click事件

    點擊<div>,將先輸出“div”,再輸出“body”。

    IE9,chrome,Firefox,Opera,Safari都支持事件冒泡,並將事件冒泡到window對象。

事件捕獲

 

    事件捕獲是由Netscape Communicator團隊提出來的,是先由最上一級的節點先接收事件,然后向下傳播到具體的節點。當用戶點擊了<div>元素,采用事件捕獲,則click事件將按照document—><html>—><body>—><div>的順序進行傳播。

    若在<div>和<body>上都定義了click事件,如下:

    點擊<div>,將先輸出“body”,再輸出“div”。

    IE9,chrome,Firefox,Opera,Safari都支持事件捕獲,但是IE8和IE8以下的版本只支持事件冒泡。盡管DOM2規范要求事件應該從document對象開始傳播,但是現在的瀏覽器實現都是從window對象開始捕獲事件。

DOM事件流

    "DOM2級事件”規定的事件流包含三個階段:事件捕獲階段,處於目標階段和事件冒泡階段。首先發生的是事件捕獲,然后是實際的目標接收到事件,最后階段是冒泡階段。以上面的HTML頁面為例,單擊<div>元素將按照下圖觸發事件:

    若在<div>和<body>上都定義了click事件,如下:

    點擊<div>,將先輸出“event catch”,再輸出“div”,最后輸出“event bubble”。

事件處理程序

    事件是用戶或瀏覽器自身執行的某種動作,而響應某個事件的函數叫做事件處理程序。HTML事件處理程序、DOM0級事件處理程序和IE事件處理程序均以“on”開頭,DOM2級事件處理程序不需要加“on”。

HTML事件處理程序

DOM0級事件處理程序

DOM2級事件處理程序

    IE9,chrome,Firefox,Opera,Safari均實現了DOM2級事件處理程序,綁定事件方法addEventListener()接收三個參數:事件名稱,事件處理函數和一個布爾值。布爾值為true,則表示在捕獲階段調用事件處理程序;如果為false,則表示在冒泡階段調用事件處理程序。addEventListener允許在同一個元素上添加多個事件處理程序,如下所示:

    先輸出“event bubble”,后輸出“event catch”,說明addEvenListener綁定的處理程序執行順序和綁定順序相同。

通過DOM2級事件處理程序指定的方法,this也引用當前元素,如下:

    輸出“myDiv”。

    刪除DOM2級事件處理程序,采用removeEventListener(),刪除時傳入的參數必須和綁定時傳入的參數相同,不能傳入匿名函數。如下所示:

IE事件處理程序

    IE8和IE8以下的版本不支持addEventListener(),而是采用attachEvent()來實現事件綁定。目前只有IE和Opera支持attachEvent()。IE9支持addEventListener(),同時也兼容IE8的attachEvent()方法,但是IE9和IE8對attachEvent()的實現有點不同。如下所示:

    IE9和IE10先輸出“1”,再輸出“2”,而IE8和IE7先輸出“2”,再輸出“1”。

    刪除IE事件處理程序,采用detachEvent(),刪除時傳入的參數必須和綁定時傳入的參數相同,不能傳入匿名函數。如下所示:

    總結:attachEvent()采用冒泡方式,而addEventListener()可以采用冒泡或事件捕獲方式。

    輸出順序:body:event catch—>parent:event catch—>child—>parent:event bubble—>body:event bubble

 

W3C

    任何發生在w3c事件模型中的事件,首是進入捕獲階段,直到達到目標元素,再進入冒泡階段。

對於正常的web開發,可以選擇是在捕獲階段還是冒泡階段綁定事件處理函數,這是通過addEventListener()方法實現的,如果這個函數的useCapture參數是true,則在捕獲階段綁定函數,反之false,在冒泡階段綁定函數。

 

element.addEventListener(event, function, useCapture)

 

阻止冒泡

 

    在正常的開發過程中,如果想要阻止事件的傳播,通過一個方法實現。

 

    在微軟的模型中,你必須設置事件的cancelBubble的屬性為true

 

window.event.cancelBubble = true

 

    在w3c模型中你必須調用事件的stopPropagation()方法

 

e.stopPropagation()

 

通過調用這些方法會阻止所有冒泡向外傳播。跨瀏覽器解決方案:

 

function doSomething(e) {

 if (!e) {

 var e = window.event;

 e.cancelBubble = true;

 }

 if (e.stopPropagation) {

 e.stopPropagation();

 }

}

 


免責聲明!

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



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