事件冒泡和事件捕獲分別由微軟和網景公司提出,這兩個概念都是爲了解決頁面中事件流(事件發生順序)的問題。javascript
以下:假設三層div都有事件監聽,這時咱們點擊的小的藍方框,事件執行的順序是怎麼樣的呢html
<div id="s1" style="height: 400px;width: 400px;border: 1px solid red">紅 <div id="s2" style="height: 200px;width: 200px;border: 1px solid yellow"> 黃 <div id="s3" style="height: 100px;width: 100px;border: 1px solid blue">藍</div> </div> </div>
微軟提出了名爲事件冒泡(event bubbling)的事件流。事件冒泡能夠形象地比喻爲把一顆石頭投入水中,泡泡會一直從水底冒出水面。也就是說,事件會從最內層的元素開始發生,一直向上傳播,直到document對象。
所以在事件冒泡的概念下在div元素上發生click事件的順序應該是div -> body -> html -> document
java
網景提出另外一種事件流名爲事件捕獲(event capturing)。與事件冒泡相反,事件會從最外層開始發生,直到最具體的元素。
所以在事件捕獲的概念下在div元素上發生click事件的順序應該是document -> html -> body -> div -> div
瀏覽器
addEventListener第三個參數默認值是false,表示在事件冒泡階段調用事件處理函數;若是參數爲true,則表示在事件捕獲階段調用處理函數。函數
s1 = document.getElementById('s1') s2 = document.getElementById('s2') s3 = document.getElementById('s3') s1.addEventListener("click",function(e){ console.log("紅 冒泡事件");//從底層往上 },false);//第三個參數默認值是false,表示在事件冒泡階段調用事件處理函數;若是參數爲true,則表示在事件捕獲階段調用處理函數。 s2.addEventListener("click",function(e){ console.log("黃 冒泡事件"); },false); s3.addEventListener("click",function(e){ console.log("藍 冒泡事件"); },false);
s1.addEventListener("click",function(e){ console.log("紅 捕獲事件"); },true); s2.addEventListener("click",function(e){ console.log("黃 捕獲事件"); },true); s3.addEventListener("click",function(e){ console.log("藍 捕獲事件"); },true);
s1.addEventListener("click",function(e){ console.log("紅 冒泡事件"); },false); s2.addEventListener("click",function(e){ console.log("黃 冒泡事件"); },false); s3.addEventListener("click",function(e){ console.log("藍 冒泡事件"); },false); s1.addEventListener("click",function(e){ console.log("紅 捕獲事件"); },true); s2.addEventListener("click",function(e){ console.log("黃 捕獲事件"); },true); s3.addEventListener("click",function(e){ console.log("藍 捕獲事件"); },true);
好比我想點擊ul標籤裏面的li獲取它的值,有點人就會遍歷去給每一個li加一個事件監聽
其實咱們能夠在li的父級加一個事件監聽,這就至關於把事件監聽委託給了ul
咱們點擊li的時候是會打出值的測試
<ul id="ul"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> <li>7</li> </ul>
ul = document.getElementById('ur') ul.addEventListener("click",function(e){ console.log(e.target.innerText); },false);
onclick不能像addEventListener那樣指定是事件類型,它只能是事件冒泡spa
s1.onclick=function(){ console.log('紅') } s2.onclick=function(){ console.log('黃') } s3.onclick=function(){ console.log('藍') return true }
但某一些時候咱們不想觸發事件冒泡怎麼辦或者是不想觸發默認的一些方法代理
這是W3C的標準方法,stopPropagation是事件對象(Event)的一個方法,做用是阻止目標元素的冒泡事件,可是會不阻止默認行爲。
IE使用的是IE則是使用e.cancelBubble = truecode
function stopBubble(e) { //若是提供了事件對象,則這是一個非IE瀏覽器 if ( e && e.stopPropagation ) //所以它支持W3C的stopPropagation()方法 e.stopPropagation(); else //不然,咱們須要使用IE的方式來取消事件冒泡 window.event.cancelBubble = true; }
preventDefault它是事件對象(Event)的一個方法,做用是取消一個目標元素的默認行爲。既然是說默認行爲,固然是元素必須有默認行爲才能被取消,若是元素自己就沒有默認行爲,調用固然就無效了。什麼元素有默認行爲呢?如連接<a>
,提交按鈕<input type=」submit」>
等。當Event 對象的 cancelable爲false時,表示沒有默認行爲,這時即便有默認行爲,調用preventDefault也是不會起做用的。htm
javascript的return false只會阻止默認行爲,而是用jQuery的話則既阻止默認行爲又防止對象冒泡。
//阻止瀏覽器的默認行爲 總結 function stopDefault( e ) { //阻止默認瀏覽器動做(W3C) if ( e && e.preventDefault ) e.preventDefault(); //IE中阻止函數器默認動做的方式 else window.event.returnValue = false; return false; }