什么是DOM樹
每個HTML頁面都是一顆DOM樹,瀏覽器在解析HTML代碼時,會按照代碼結(jié)構(gòu)將代碼解析成一顆樹狀結(jié)構(gòu),每個HTML標(biāo)簽對應(yīng)DOM樹上相應(yīng)的結(jié)點。
比如下面的代碼:
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div id='c1'>
<ul>
<li><a href="#">點我</a></li>
</ul>
</div>
</body>
</html>
對應(yīng)的DOM樹為:

什么是事件捕獲與事件冒泡
以上圖為例,我們給div添加一個事件響應(yīng)函數(shù)
var c1=document.getElementById('c1');
c1.addEventListener('click',function(e){
console.log(e.target.nodeName)
});
當(dāng)點擊“點我”的時候,瀏覽器就會尋找發(fā)生點擊事件的事件源,從上到下,依次找到body->div->ul->li->a
這個從上到下尋找事件源的過程就叫做事件捕獲。
找到了事件源a標(biāo)簽,a標(biāo)簽上的點擊事件就會像泡泡一樣傳遞到它的上一級li,進而傳遞到ul、div、body,這個與事件捕獲傳遞方向相反的過程就叫做事件冒泡。
在事件冒泡過程中,不管該節(jié)點有沒有綁定事件響應(yīng)函數(shù),冒泡都會繼續(xù),當(dāng)a標(biāo)簽上的點擊事件傳遞到div上時,div上有點擊事件響應(yīng)函數(shù),然后就會執(zhí)行這個函數(shù),console.log(e.target.nodeName),輸出事件源。
同樣的點擊li、ul、div也會執(zhí)行類似過程,這樣就可以只用一個響應(yīng)函數(shù)來處理4次不同的點擊事件。
取消事件冒泡
使用event對象的stopPropagation() 方法
如果在a、li、ul這三個節(jié)點任一節(jié)點上使用stopPropagation() 方法,冒泡過程就會終止,div就監(jiān)聽不到點擊事件,它的響應(yīng)函數(shù)也不會執(zhí)行
var li=c1.getElementsByTagName('li')[0];
li.addEventListener('click',function(e){
console.log(this.tagName);
e.stopPropagation();
})
在li上取消事件冒泡,這時再點擊a標(biāo)簽,事件傳遞到li上就會停止,console.log只會輸出li而不會輸出a。
如果點擊的是ul標(biāo)簽,console.log會輸出ul,這是另外一個點擊事件,中間沒有取消冒泡,妥妥的被div捕捉到