科普下事件冒泡以及默認行為,以下面例子舉列子:
事件冒泡:當點擊內部button元素時,會觸發自身及外層 a的點擊事件,這就是事件冒泡引起的。事件會隨着 DOM 的層次結構依次向上傳播。
事件冒泡可能會引起意料之外的效果,有時候需要阻止事件的冒泡行為。
默認行為:例子中a的href跳轉鏈接就是所謂的默認行為,或者是表單form的提交。
JQuery中阻止冒泡常用到的有以下3個方法:
1:event.stopPropagation(); 只阻止了冒泡事件, 默認行為沒有阻止
2:event.preventDefault(); 只阻止了默認事件,冒泡事件沒有阻止
3:return false; 冒泡事件和默認事件都阻止
具體對應列子:
1:event.stopPropagation();
1 <body> 2 <a id="p" href="http://www.baidu.com" target="_blank">我是超級鏈接<button id="sub">子按鈕</button></a> 3 <div id="text"> 4 </div> 5 </body>
1 <script> 2 $(function(){ 3 $("#p").click(function(event){ 4 $("#text").append("<p>父親元素被點擊</p>"); 5 }) 6 7 $("#sub").click(function(event){ 8 $("#text").append("<p>子元素被點擊</p>"); 9 event.stopPropagation(); //只阻止了冒泡事件, 默認默認行為沒有阻止 10 11 }) 12 }) 13 </script>
效果截圖:
默認點擊父親元素:
默認點擊子元素,事件冒泡了:
加上event.stopPropagation(),可以看到阻止了父親的單擊事件,但是沒有阻止父親a元素hreaf的默認行為,也就是打開新的窗口:
2:event. preventDefault();
1 <script> 2 $(function(){ 3 $("#p").click(function(event){ 4 $("#text").append("<p>父親元素被點擊</p>"); 5 }) 6 7 $("#sub").click(function(event){ 8 $("#text").append("<p>子元素被點擊</p>"); 9 event.preventDefault(); //只阻止了默認事件,冒泡事件沒有阻止 10 }) 11 }) 12 </script>
event. preventDefault()加上后,有阻止了默認行為,沒有打開新的href窗口,但是沒有阻止冒泡事件,父親的click還是觸發了:

3:return false;
1 <script> 2 $(function(){ 3 $("#p").click(function(event){ 4 $("#text").append("<p>父親元素被點擊</p>"); 5 }) 6 7 $("#sub").click(function(event){ 8 $("#text").append("<p>子元素被點擊</p>"); 9 return false; //冒泡事件和默認事件都阻止 10 }) 11 }) 12 </script>
return false加上后既沒有冒泡,也沒有打開新窗口:

以上就是工作上經常用到的阻止冒泡和默認行為的方法。實際情況根據需求確定使用哪種方法
這里再說明一下如果是動態生成的元素用on來綁定事件,遇到的阻止冒泡的一些問題,大家參考一下下面是我測試的幾個列子:
1:父親跟孩子同時用on來綁定:
A:綁定的父節點不是同一個,父親綁定的父元素更外面(綁定body):
1 <body id="body"> 2 <div id="bb"> 3 <a id="p" href="http://www.baidu.com" target="_blank" >我是超級鏈接<button id="sub">子按鈕</button></a> 4 </div> 5 <div id="text"> 6 </div> 7 </body>
1 <script> 2 $(function(){ 3 /父親節點a綁定到body中 4 $("#body").on("click","#p",function(event){ 5 $("#text").append("<p>父親元素被點擊</p>"); 6 }) 7 //孩子節點綁定在div中 8 $("#bb").on("click","#sub",function(event){ 9 $("#text").append("<p>子元素被點擊</p>"); 10 event.stopPropagation(); //只阻止了冒泡事件, 默認默認行為沒有阻止 11 }) 12 }) 13 </script>
測試結果:有阻止冒泡事件

B:綁定的父節點不是同一個,孩子綁定的父元素更外面(綁定body)
1 <script> 2 $(function(){ 3 /父親節點a綁定到div中 4 $("#bb").on("click","#p",function(event){ 5 $("#text").append("<p>父親元素被點擊</p>"); 6 }) 7 //孩子節點綁定在body中 8 $("#body").on("click","#sub",function(event){ 9 $("#text").append("<p>子元素被點擊</p>"); 10 event.stopPropagation(); //只阻止了冒泡事件, 默認默認行為沒有阻止 11 }) 12 }) 13 </script>
測試結果:阻止冒泡失敗,並且是父親元素a的click先觸發

C:綁定的父節點是同一個:
都綁定在body或者div上,測試結果正常,有阻止冒泡事件:
2:父親直接寫onclick事件,孩子直接用on綁定
1 <body id="body"> 2 <div id="bb"> 3 <a id="p" href="http://www.baidu.com" target="_blank" onclick="test()">我是超級鏈接<button id="sub">子按鈕</button></a> 4 </div> 5 <div id="text"> 6 </div> 7 </body>
1 <script> 2 $(function(){ 3 $("#bb").on("click","#sub",function(event){ 4 $("#text").append("<p>子元素被點擊</p>"); 5 event.stopPropagation(); //只阻止了冒泡事件, 默認默認行為沒有阻止 6 }) 7 }) 8 function test(){ 9 $("#text").append("<p>父親元素被點擊</p>"); 10 } 11 </script>
測試結果:阻止冒泡失敗,並且是父親元素a的click先觸發

3:孩子直接寫onclick事件,父親直接用on綁定
1 <body id="body"> 2 <div id="bb"> 3 <a id="p" href="http://www.baidu.com" target="_blank">我是超級鏈接<button id="sub" onclick="test(event)">子按鈕</button></a> 4 </div> 5 <div id="text"> 6 </div> 7 </body>
1 <script> 2 $(function(){ 3 //父親綁定到body 4 $("#body").on("click","#p",function(event){ 5 $("#text").append("<p>父親元素被點擊</p>"); 6 }) 7 }) 8 function test(event){ //event在onclick那邊直接傳入,這樣才支持所有瀏覽器 9 $("#text").append("<p>子元素被點擊</p>");
event.stopPropagation(); 10 } 11 </script>
測試結果:阻止冒泡成功

好了,以上有涉及on綁定做的測試總結如下:
1:父親跟孩子同時用on來綁定:
A:綁定的父節點不是同一個,父親綁定的父元素更外面(綁定body) 阻止冒泡事件成功
B:綁定的父節點不是同一個,孩子綁定的父元素更外面(綁定body) 阻止冒泡失敗,並且是父親元素a的click先觸發
C:綁定的父節點是同一個: 阻止冒泡事件成功
2:父親直接寫onclick事件,孩子直接用on綁定 阻止冒泡失敗,並且是父親元素a的click先觸發
3:孩子直接寫onclick事件,父親直接用on綁定 阻止冒泡成功
常規JQuery中阻止冒泡常用到的有以下3個方法:
1:event.stopPropagation(); 只阻止了冒泡事件, 默認行為沒有阻止
2:event.preventDefault(); 只阻止了默認事件,冒泡事件沒有阻止
3:return false; 冒泡事件和默認事件都阻止
