DOM模型是一個樹形結構,在DOM模型中,HTML元素是有層次的。當一個HTML元素上產生一個事件時,該事件會在DOM樹中元素節點與根節點之間按特定的順序傳播,路徑所通過的節點都會收到該事件,這個傳播過程就是DOM事件流。javascript
當事件發生後,這個事件就要開始傳播(從裏到外或者從外向裏)。爲何要傳播呢?由於事件源自己(可能)並無處理事件的能力,即處理事件的函數(方法)並未綁定在該事件源上。例如咱們點擊一個按鈕時,就會產生一個click事件,但這個按鈕自己可能不能處理這個事件,事件必須從這個按鈕傳播出去,從而到達可以處理這個事件的代碼中(例如咱們給按鈕的onclick屬性賦一個函數的名字,就是讓這個函數去處理該按鈕的click事件),或者按鈕的父級綁定有事件函數,當該點擊事件發生在按鈕上,按鈕自己並沒有處理事件函數,則傳播到父級去處理。css
DOM事件標準定義了兩種事件流,分別是捕獲事件和冒泡事件。html
事件捕獲指的是從document到觸發事件的那個節點,即自上而下的去觸發事件。相反的,事件冒泡是自下而上的去觸發事件。java
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>事件冒泡</title> <script type="text/javascript" src="../jquery-1.11.2.min.js"></script> <style type="text/css"> #a { width: 200px; height: 200px; background-color: gray; } #b { width: 100px; height: 100px; background-color: pink; } </style> </head> <body> <div id="a"> <div id="b"> <a href="http://www.baidu.com" target="_blank">百度一下</a> </div> </div> <script type="text/javascript"> document.getElementById("a").addEventListener("click", function(e) { console.log("a事件被觸發," + this.id); }, true); document.getElementById("b").addEventListener("click", function(e) { console.log("b事件被觸發," + this.id); }, true); </script> </body> </html>
綁定事件方法的第三個參數,就是控制事件觸發順序是否爲事件捕獲。true,事件捕獲;false,事件冒泡。默認false,即事件冒泡。因此當你對一個dom節點觸發事件時,若外層的節點也設置了相應的事件函數,就會使外層的節點也觸發本身的事件函數。node
當兩個都爲false時,結果爲:jquery
點擊a,只觸發a事件:dom
點擊b,同時觸發ab事件(先b後a,事件冒泡):函數
當兩個都爲true時:性能
點擊a,只觸發a事件:this
點擊b,同時觸發ab事件(先a後b,事件捕獲):
若是想要阻止事件冒泡:
event.stopPropagation()方法
這是阻止事件的冒泡方法,不讓事件向documen上蔓延,可是默認事件任然會執行,當你掉用這個方法的時候,若是點擊一個鏈接,這個鏈接仍然會被打開。阻止事件冒泡只須要將event.stopPropagation()插入到console.log前。阻止事件a冒泡,第三個參數爲false,將event.stopPropagation()插入到b事件函數的console.log前,結果,點擊b,只執行b:
event.preventDefault()方法
這是阻止默認事件的方法,調用此方法是,鏈接不會被打開,可是會發生冒泡,冒泡會傳遞到上一層的父元素。
return false ;
它會同時阻止事件冒泡也會阻止默認事件;寫上此代碼,鏈接不會被打開,事件也不會傳遞到上一層的父元素;能夠理解爲return false就等於同時調用了event.stopPropagation()和event.preventDefault()
事件委託:
當有多個相似的元素須要綁定事件時,一個一個去綁定即浪費時間,又不利於性能,這時候就能夠用到事件委託,給他們的一個共同父級元素添加一個事件函數去處理他們全部的事件狀況。
e.target表示在事件冒泡中觸發事件的源元素,在IE中是e.srcElement 而且e.target有不少屬性能夠操做 event.target.nodeName //獲取事件觸發元素標籤name(li,p…) event.target.id //獲取事件觸發元素id event.target.className //獲取事件觸發元素classname event.target.innerHTML //獲取事件觸發元素的內容(li)