本文转载自掘金中我的小伙伴的一篇文章:https://juejin.im/post/5bf7ad096fb9a049ed308353
什么是事件冒泡?
当事件发生后,这个事件就要开始传播(从里到外,或者从外向里)。为什么要传播呢?因为事件源本身(可能)并没有处理事件的能力,或处理事件的函数并未绑定在该事件源上。如下图:
我们经常利用事件冒泡机制去减少给DOM添加过多的绑定事件即事件委托,但是有时候事件冒泡也会比较烦人,影响我们的事件正常处理机制,如下:
 
  - 
   
    
   
   
    
     <body>
    
   
  
 - 
   
    
   
   
    
     <div id="info">
    
   
  
 - 
   
    
   
   
     
     <div class="box-1" onclick="box1()">
    
   
  
 - 
   
    
   
   
    
      最外层
    
   
  
 - 
   
    
   
   
     
     <div class="box-2" onclick="box2()">
    
   
  
 - 
   
    
   
   
    
      第二层
    
   
  
 - 
   
    
   
   
     
     <div class="box-3" onclick="box3()">
    
   
  
 - 
   
    
   
   
    
      第三层
    
   
  
 - 
   
    
   
   
     
     <div class="box-4" onclick="bubbles()">最底
     </div>
    
   
  
 - 
   
    
   
   
     
     </div>
    
   
  
 - 
   
    
   
   
     
     </div>
    
   
  
 - 
   
    
   
   
     
     </div>
    
   
  
 - 
   
    
   
   
    
     </div>
    
   
  
 - 
   
    
   
   
    
     <script>
     
    
   
  
 - 
   
    
   
   
     
     function bubbles(){
    
   
  
 - 
   
    
   
   
     
     console.log(
     "最底层盒子被点击了")
    
   
  
 - 
   
    
   
   
    
      }
    
   
  
 - 
   
    
   
   
     
    
   
  
 - 
   
    
   
   
     
     function box1(){
    
   
  
 - 
   
    
   
   
     
     console.log(
     "最外层盒子被点击了");
    
   
  
 - 
   
    
   
   
    
      }
    
   
  
 - 
   
    
   
   
     
    
   
  
 - 
   
    
   
   
     
     function box2(){
    
   
  
 - 
   
    
   
   
     
     console.log(
     "第二个盒子被点击了");
    
   
  
 - 
   
    
   
   
    
      }
    
   
  
 - 
   
    
   
   
     
    
   
  
 - 
   
    
   
   
     
     function box3(){
    
   
  
 - 
   
    
   
   
     
     console.log(
     "第三个盒子被点击了");
    
   
  
 - 
   
    
   
   
    
      }
    
   
  
 - 
   
    
   
   
    
     </script>
    
   
  
 - 
   
    
   
   
    
     </body>复制代码
    
   
 
 
   
如何阻止事件冒泡?
由上图我们可以看出,我们只点击了最里面的那个div,但是在他的父级及以上div身上所绑定的事件都被触发了,这显然不是我们想要的结果,我们实际需求是只想要触发点击的那个div上绑定的事件,我们该如何阻止浏览器的这种事件处理机制呢?
 
  - 
   
    
   
   
    
     function bubbles(e){
    
   
  
 - 
   
    
   
   
     
     var ev = e || 
     window.event;
    
   
  
 - 
   
    
   
   
     
     if(ev && ev.stopPropagation) {
    
   
  
 - 
   
    
   
   
     
     //非IE浏览器
    
   
  
 - 
   
    
   
   
    
      ev.stopPropagation();
    
   
  
 - 
   
    
   
   
    
      } 
     else {
    
   
  
 - 
   
    
   
   
     
     //IE浏览器(IE11以下)
    
   
  
 - 
   
    
   
   
    
      ev.cancelBubble = 
     true;
    
   
  
 - 
   
    
   
   
    
      }
    
   
  
 - 
   
    
   
   
     
     console.log(
     "最底层盒子被点击了")
    
   
  
 - 
   
    
   
   
    
     }复制代码
    
   
 
 
   
这样我们就可以实现点击哪个div触发哪个div的方法,而对其他div不造成影响了
阻止默认事件
一共有如下三种方式:
 
  - 
   
    
   
   
    
     //谷歌及IE8以上
    
   
  
 - 
   
    
   
   
    
     e.preventDefault();
    
   
  
 - 
   
    
   
   
    
     //IE8及以下
    
   
  
 - 
   
    
   
   
    
     window.event.returnValue = 
     false;
    
   
  
 - 
   
    
   
   
    
     //无兼容问题(但不能用于节点直接onclick绑定函数)
    
   
  
 - 
   
    
   
   
    
     return 
     false;复制代码
    
   
 
 
   具体用法:
 
  - 
   
    
   
   
    
     <!doctype html>
    
   
  
 - 
   
    
   
   
    
     <html lang="en">
    
   
  
 - 
   
    
   
   
    
     <head>
    
   
  
 - 
   
    
   
   
     
     <meta charset="UTF-8">
    
   
  
 - 
   
    
   
   
     
     <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    
   
  
 - 
   
    
   
   
     
     <meta http-equiv="X-UA-Compatible" content="ie=edge">
    
   
  
 - 
   
    
   
   
     
     <title>阻止默认事件
     </title>
    
   
  
 - 
   
    
   
   
    
     </head>
    
   
  
 - 
   
    
   
   
    
     <body>
    
   
  
 - 
   
    
   
   
    
     <div id="info">
    
   
  
 - 
   
    
   
   
     
     <a href="www.baidu.com" id="test">阻止默认事件
     </a>
    
   
  
 - 
   
    
   
   
    
     </div>
    
   
  
 - 
   
    
   
   
    
     <script>
     
    
   
  
 - 
   
    
   
   
     
     var aDom = 
     document.getElementById(
     'test');
    
   
  
 - 
   
    
   
   
    
      aDom.onclick = 
     function ( e ){
    
   
  
 - 
   
    
   
   
     
     if(e && e.preventDefault) {
    
   
  
 - 
   
    
   
   
     
     //非IE浏览器
    
   
  
 - 
   
    
   
   
    
      e.preventDefault();
    
   
  
 - 
   
    
   
   
    
      } 
     else {
    
   
  
 - 
   
    
   
   
     
     //IE浏览器(IE11以下)
    
   
  
 - 
   
    
   
   
     
     window.event.returnValue = 
     false;
    
   
  
 - 
   
    
   
   
    
      }
    
   
  
 - 
   
    
   
   
     
     //return false; //或者不写上面的判断直接写这句
    
   
  
 - 
   
    
   
   
    
      };
    
   
  
 - 
   
    
   
   
    
     </script>
    
   
  
 - 
   
    
   
   
    
     </body>
    
   
  
 - 
   
    
   
   
    
     </html>复制代码
    
   
 
 
   使用return false的注意点
 
  - 
   
    
   
   
    
     <!doctype html>
    
   
  
 - 
   
    
   
   
    
     <html lang="en">
    
   
  
 - 
   
    
   
   
    
     <head>
    
   
  
 - 
   
    
   
   
     
     <meta charset="UTF-8">
    
   
  
 - 
   
    
   
   
     
     <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    
   
  
 - 
   
    
   
   
     
     <meta http-equiv="X-UA-Compatible" content="ie=edge">
    
   
  
 - 
   
    
   
   
     
     <title>阻止默认事件
     </title>
    
   
  
 - 
   
    
   
   
    
     </head>
    
   
  
 - 
   
    
   
   
    
     <body>
    
   
  
 - 
   
    
   
   
    
     <div id="info">
    
   
  
 - 
   
    
   
   
     
     <a href="www.baidu.com" onclick="defaultEvent()">阻止默认事件
     </a>
    
   
  
 - 
   
    
   
   
    
     </div>
    
   
  
 - 
   
    
   
   
    
     <script>
     
    
   
  
 - 
   
    
   
   
     
     function defaultEvent(){
    
   
  
 - 
   
    
   
   
     
     return 
     false;
    
   
  
 - 
   
    
   
   
    
      }
    
   
  
 - 
   
    
   
   
    
     </script>
    
   
  
 - 
   
    
   
   
    
     </body>
    
   
  
 - 
   
    
   
   
    
     </html>复制代码
    
   
 
 
   以上代码,完全无效,无法通过这个函数阻止a标签的跳转,return false不能适用于直接用onclick绑定的事件,所以当我们使用这种绑定事件方式时,我们还是需要采用e.preventDefault()这个函数
在jQuery中使用return false时,相当于同时使用event.preventDefault和event.stopPropagation,它会阻止冒泡也会阻止默认行为。 但是使用原生js写时,return false只会阻止默认行为。
  

京公网安备 11010502036488号