事件流描述的是從頁面中接收事件的順序。說白了,我作了一件事,這件事怎麼被別人知道的,這個順序就是事件流。 可是對於這個順序,有些人產生了分歧。IE和Netscape提出了幾乎是徹底相反的事件流的概念。因而有了(IE)事件冒泡流和(Netscape)事件捕獲流。html
事件冒泡:事件開始時由最具體的元素(文檔中嵌套層次最深的那個節點)接收,而後逐級向上傳播到較爲不具體的節點(文檔)。 以下示例:瀏覽器
<!DOCTYPE html>
<html>
<head>
<title>事件冒泡</title>
</head>
<body>
<div id="myDiv">點我</div>
</body>
</html>
複製代碼
若是你點擊了裏面的<div>
元素,那麼click事件就會按照下面的順序傳播執行:bash
<div>
<body>
<html>
document
click事件會首先在<div>
元素身上發生,這個元素就是咱們點擊的的元素,而後纔是上一層元素,一直到document元素。函數
事件捕獲:不太具體的節點應該更早接收事件,而最具體的節點應該是最後接收到事件。那麼點擊<div>
元素就會如下列順序執行click事件:this
document
<html>
<body>
<div>
事件捕獲過程,document對象首先接收到click事件,而後依次向下,傳播到事件的實際目標。spa
事件流規定包含三個流程:事件捕獲階段,事件冒泡階段和處於目標階段。首先發生是事件捕獲(截獲事件),而後是處於目標階段接收到事件,最後是事件冒泡階段(對事件做出相應)。3d
在DOM事件流中,目標元素<div>
在事件捕獲階段是不會接受到事件的,下一階段「處於目標階段」,事件在<div>
上發生,並在事件處理中被當作冒泡階段的一部分,而後,冒泡階段發生,事件傳播迴文檔。code
在上文中的事件處理,就是咱們使用事件流的一種方法,事件是用戶或者瀏覽器自身執行的某種動做,例如'click'、'mouseover'等都是事件的名字,而相應這種操做的函數就叫事件處理程序(事件偵聽)。cdn
經過JavaScript指定事件處理程序的傳統方法,就是將一個函數賦值給一個事件處理程序屬性。每一個元素(包括window和document)都有本身的事件處理程序屬性,這些屬性所有小寫。以下:htm
var button = document.getElementById('myButton')
button.onclick = function(){
alert('hello'+this.id)
}
複製代碼
咱們經過文檔對象獲取到一個button的引用,並給它了一個onclick的事件處理程序。可是須要注意的是:若是這段代碼運行在button的後面,可能會出現你怎麼點擊都沒有反應。
DOM0級方法指定的事件處理程序被認爲是元素的方法。所以,這個時候的事件處理程序是在該元素的做用域中執行。因此代碼塊裏面會alert出‘myButton’,往大了說,在這個事件處理程序的做用域中,能夠用this訪問到該元素的任何方法和屬性。這種方式添加的事件處理程序會在事件流的冒泡階段被處理。
若是想要刪除這個DOM0級事件處理程序,以下:
button.onclick = null
複製代碼
再點擊就不會有任何反應。
DOM2級事件處理程序定義了兩個方法:‘addEventListener()’和‘removeEventListener()’,全部DOM節點都包含這兩個方法,而且它們接收3個參數:要處理的事件名、事件處理的函數、一個布爾值。
var button = document.getElementById('myButton')
button.addEventListener('click', function(){
alert('hello'+this.id)
}, false)
複製代碼
和DOM0級事件處理程序同樣,這個this.id打印仍是‘myButton’,其做用域仍然在依附的元素中。使用DOM2級事件處理程序的好處是能夠添加多個事件,那麼事件就會按照添加它們的順序執行。
經過addEventListener()添加的時間處理程序,只能經過removeEventListener()來刪除。
button.removeEventListener('click', function(){
alert('hello'+this.id)
}, false)
複製代碼
上面這樣作是沒有用的,由於removeEventListener(),須要傳入同樣的參數,表面上你確實參數傳的同樣,其實否則,裏面有個匿名函數,因此你的第二參數永遠都不會同樣。
var button = document.getElementById('myButton')
var pomelo = function(){
alert('hello'+this.id)
}
button.addEventListener('click', pomelo, false)
button.removeEventListener('click', pomelo, false)
複製代碼
上面這樣纔是真正的刪除了。
大多數狀況下,都是將事件處理程序添加到事件流的冒泡階段,若是不是特別的需求,建議添加到冒泡階段。