假設有這麼一段代碼javascript
<body> <div><p>標籤</p> </div> </body>
轉換成圖以下html
咱們知道Dom是有節點關係的java
body -> div -> p 之間的關係就是 爺爺 -> 父親 -> 兒子。
咱們來思考一個關鍵的問題瀏覽器
若是此時咱們在 body div p 都綁定一個點擊事件(click)。此時若是咱們只點擊 p標籤,它會不會觸發div綁定事件 和 body綁定事件?this
答案是會的3d
那這個時候就會有一個問題,既然點擊 p標籤 會觸發 div綁定事件 和 body綁定事件,那執行順序是怎麼樣的呢?code
body事件 -> div事件 -> p事件? 仍是 p事件 -> div事件 -> body事件?
這兩種不一樣的執行順序就是對應上面的 事件冒泡 和 事件捕獲。htm
事件捕獲
事件從最上一級標籤開始往下查找,直到捕獲到事件目標(body事件 -> div事件 -> p事件)。對象
事件冒泡
事件從事件目標開始,往上冒泡直到頁面的最上一級標籤( p事件 -> div事件 -> body事件)blog
爲了避免混淆記憶它們,這裏有個通俗的理解冒泡:
冒泡嘛,就像水裏往上冒的泡泡,從一開始很小,而後慢慢變大直到破裂。因此是從小到大,也就是子標籤到父標籤傳遞的過程。那麼事件捕獲記住與冒泡相反就能夠了。
代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>事件冒泡</title> <style> #dv1{ /*爲了直觀 這裏添加些樣式*/ width: 300px; height: 200px; background-color: red; } #dv2{ width: 250px; height: 150px; background-color: green; } #dv3{ width: 200px; height: 100px; background-color: blue; } </style> </head> <body> <div id="dv1">爺爺 <div id="dv2">父親 <div id="dv3">兒子</div> </div> </div> <script> //事件冒泡:多個元素嵌套,有層次關係,這些元素都註冊了相同的事件,若是裏面的元素的事件觸發了,外面的元素的該事件自動的觸發了. document.getElementById("dv1").onclick=function () { console.log(this.id+" 爺爺"); }; document.getElementById("dv2").onclick=function () { console.log(this.id+" 父親"); }; //事件處理參數對象 document.getElementById("dv3").onclick=function (e) { console.log(this.id+" 兒子"); //阻止事件冒泡 //e.stopPropagation(); }; </script> </body> </html>
運行結果
從這個示例咱們能夠看出3點
一、當點擊兒子元素後,父親和爺爺的點擊事件也觸發了。 二、onclick事件的順序 兒子 - 父親 - 爺爺。 三、當點擊爺爺元素後,父親和兒子的點擊是不會觸發的。
既然有冒泡事件,那確定在實際開放過程當中,你不須要冒泡,你只想兒子點擊觸發事件,父親和爺爺不觸發事件。
語法
一、window.event.cancelBubble=true; IE特有的,谷歌支持,火狐不支持 二、e.stopPropagation(); 谷歌和火狐支持
由於我用的是谷歌瀏覽器,因此這裏用第二種方式阻止冒泡(只需把上面阻止事件冒泡的代碼取消註釋就能夠了)
運行結果
從運行結果很明顯看出,已經阻止了事件冒泡。
示例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>title</title> <style> #dv1 { width: 300px; height: 200px; background-color: red; } #dv2 { width: 250px; height: 150px; background-color: green; } #dv3 { width: 200px; height: 100px; background-color: blue; } </style> </head> <body> <div id="dv1">爺爺 <div id="dv2">父親 <div id="dv3">兒子</div> </div> </div> <script> //爲每一個元素綁定事件 這裏 /** * 捕獲時間 從外到裏 * 一、 addEventListener不是每一個瀏覽器都兼容的 * 二、 這裏true爲事件捕獲 false爲事件冒泡 */ document.getElementById("dv1").addEventListener("click", function (e) { console.log(this.id+" 爺爺"); }, true); document.getElementById("dv2").addEventListener("click", function (e) { console.log(this.id+" 父親"); }, true); document.getElementById("dv3").addEventListener("click", function (e) { console.log(this.id+" 兒子"); }, true); </script> </body> </html>
運行
很明顯,這裏是從外到裏執行事件。
你若是願意有所做爲,就必須善始善終。(22)