事件冒泡
事件冒泡是由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(); } } |