JQuery阻止冒泡事件on绑定中异常情况分析
科普下事件冒泡以及默认行为,以下面例子举列子:
事件冒泡:当点击内部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; 冒泡事件和默认事件都阻止