對“捕獲”和“冒泡”這兩個概念,通常我們對冒泡了解和使用的會更多一些,因為在我們使用的所有瀏覽器中,都支持事件冒泡 ,即事件由子元素向祖先元素傳播的,就 像氣泡從水底向水面上浮一樣。而在像firefox,chrome,safari這類所謂的標准瀏覽器中,事件傳播通常是有三個階段的:事件捕獲階段,事 件目標階段,事件冒泡階段,這三者的執行的順序是先捕獲在冒泡。對於捕獲階段,這個很少 有用武之地,所以被人疏忽遺忘也在所難免了,不常用不代表它不存在,本着科學嚴謹的態度,我們有必要去看一下它的廬山真面目。
事件冒泡:事 件冒泡指的是當前的目標元素觸發事件的發生,事件在一次向祖先元素傳播,在祖先元素上觸發相同類型的事件。當子元素都有同一事件處理程序時,利用事件的冒 泡可以減少代碼的冗余度。通過給元素對象綁定事件的方法addEventlistener()第三個參數決定事件的執行階段是在冒泡階段還是捕獲階段,當 第三個參數為false時,為冒泡階段,通常省略該參數是默認的是冒泡,如果為true則是捕獲階段。為了兼容IE8以及IE8之前版本瀏覽器可以通過 attachEvent()方法給元素添加事件不過他沒有第三個參數。下面的例子是沒有阻止事件冒泡時的代碼,最終會看到,當點擊了ele2時,事件會向 上冒泡依次輸出ele2,ele,ele0,這個就是由於事件的冒泡引起的。
1 <html> 2 <head> 3 <meta charset="utf-8"> 4 <title>bubble event</title> 5 <style> 6 .ele0{ 7 width:400px; 8 height:400px; 9 border:1px solid black; 10 background-color:red; 11 position:relative; 12 } 13 .ele1{ 14 width:300px; 15 height:300px; 16 border:1px ; 17 background-color:green; 18 position:absolute; 19 top:0; 20 } 21 .ele2{ 22 width:200px; 23 height:200px; 24 border:1px ; 25 background-color:blue; 26 position:absolute; 27 top:0; 28 } 29 </style> 30 <script> 31 window.onload=function(){ 32 var ele=document.getElementsByTagName("div"); 33 34 if(ele[0].addEventListener) 35 { 36 ele[0].addEventListener("click", function (){ 37 38 console.log("點擊的是盒子ele0!"); 39 }); 40 } 41 42 else{ 43 ele[0].attachEvent("onclick",function (){ 44 console.log("點擊的是盒子ele0!"); 45 46 }); 47 } 48 if(ele[1].addEventListener) 49 { 50 ele[1].addEventListener("click", function (){ 51 52 console.log("點擊的是盒子ele1!"); 53 }); 54 } 55 56 else{ 57 ele[1].attachEvent("onclick",function (){ 58 console.log("點擊的是盒子ele1!"); 59 60 }); 61 } 62 63 if(ele[2].addEventListener) 64 { 65 ele[2].addEventListener("click", function (){ 66 67 console.log("點擊的是盒子ele2!"); 68 }); 69 } 70 71 else{ 72 ele[2].attachEvent("onclick",function (){ 73 console.log("點擊的是盒子ele2!"); 74 75 }); 76 } 77 78 } 79 </script> 80 </head> 81 <body> 82 <div class="ele0"> 83 <div class="ele1"><div class="ele2"></div></div> 84 85 </div> 86 </body> 87 <html>
事件捕獲:事 件捕獲過程與事件的冒泡階段是一個相反的階段,即事件由祖先元素向子元素傳播,和一個石子兒從水面向水底下沉一樣,要說明的是在 IE,opera瀏覽器中,是不存在這個階段的。在上述的代碼中給事件監聽程序添加第三個參數false,當點擊元素ele2時會看到不一樣的效果,輸出 結果中將會最先輸出ele0,而不是ele2,這就是事件的捕獲。
阻止事件的冒泡:
有時候事件的冒泡回會導致程序的運行順序和自己想象的情形不一樣,這時候就需要對事件的冒泡進行阻止。阻止事件的冒泡的方法與事件處理程序的添加方式有關:
1. 在除IE以外其他的瀏覽器中通過e.stopPropagation()方式阻止事件的冒泡。在 支持該方法的瀏覽器中還有一個方法stopimmediatePropagation(),該方法不僅會組織事件向祖元素的冒泡,同時也會阻止同一個節點 上同一事件的其他的事件處理程序的執行,該方法比前者阻止的更徹底。
2.在IE瀏覽器中通過e.cancleBubble=true,阻止事件冒泡。
1 <html> 2 <head> 3 <meta charset="utf-8"> 4 <title>bubble event</title> 5 <style> 6 .ele0{ 7 width:400px; 8 height:400px; 9 border:1px solid black; 10 background-color:red; 11 position:relative; 12 } 13 .ele1{ 14 width:300px; 15 height:300px; 16 border:1px ; 17 background-color:green; 18 position:absolute; 19 top:0; 20 } 21 .ele2{ 22 width:200px; 23 height:200px; 24 border:1px ; 25 background-color:blue; 26 position:absolute; 27 top:0; 28 } 29 </style> 30 <script> 31 window.onload=function(){ 32 var ele=document.getElementsByTagName("div"); 33 34 if(ele[0].addEventListener) 35 { 36 ele[0].addEventListener("click", function (e){ 37 38 console.log("點擊的是盒子ele0!"); 39 e.stopPropagation(); 40 }); 41 42 } 43 44 else{ 45 ele[0].attachEvent("onclick",function (e){ 46 console.log("點擊的是盒子ele0!"); 47 e=window.event; 48 e.cancleBubble=true; 49 50 }); 51 } 52 if(ele[1].addEventListener) 53 { 54 ele[1].addEventListener("click", function (e){ 55 56 console.log("點擊的是盒子ele1!"); 57 e.stopPropagation(); 58 }); 59 } 60 61 else{ 62 ele[1].attachEvent("onclick",function (e){ 63 console.log("點擊的是盒子ele1!"); 64 e=window.event; 65 e.cancleBubble=true; 66 67 }); 68 } 69 70 if(ele[2].addEventListener) 71 { 72 ele[2].addEventListener("click", function (e){ 73 74 console.log("點擊的是盒子ele2!"); 75 e.stopPropagation(); 76 }); 77 } 78 79 else{ 80 ele[2].attachEvent("onclick",function (e){ 81 console.log("點擊的是盒子ele2!"); 82 e=window.event; 83 e.cancleBubble=true; 84 85 }); 86 } 87 88 } 89 </script> 90 </head> 91 <body> 92 <div class="ele0"> 93 <div class="ele1"><div class="ele2"></div></div> 94 95 </div> 96 </body> 97 <html>
阻止事件的默認行為:
1、在IE瀏覽器中通過e.returnValue=false
2、在其他瀏覽器中調用方法e.preventDefault();
3、在jQuery中通過在事件回調利用return false(其實質利用了上面的兩種方式)實現阻止事件的默認行為
