浅谈javascript事件冒泡与事件捕获

什么是DOM事件?

事件分为DOM 0级事件和Dom 2级事件,DOM2级事件也叫做事件监听。DOM 0级事件的缺点是如果事件相同 后者的事件会覆盖前者的事件,DOM2级事件可以解决这个问题。

 

DOM2级事件的方法是?

addEventListener() 
        参数1:事件类型  不需要加on   
        参数2:回调函数    
        参数3:布尔值  true代表捕获   false代表冒泡
    解绑事件方法:removeEventListener()    
    但是IE不支持此方法
    IE浏览器下用:attachEvent()
        参数1:事件类型  需要加on
        参数2:回调函数
    解绑事件方法:detachEvent()

什么是DOM事件流?

当一个HTML元素产生一个事件时,该事件会在元素节点与根节点之间的路径传播,路径所经过的节点都会收到该事件,这个传播的过程叫做DOM事件流。
DOM事件流:将事件分为三个阶段:捕获阶段、目标阶段、冒泡阶段。先调用捕获阶段的处理函数,其次调用目标阶段的处理函数,最后调用冒泡阶段的处理函数。当发出一个URL请求的时候,先调用前置拦截器,其次调用action,最后调用后置拦截器。

什么是事件冒泡?什么是事件捕获?

冒泡事件:微软提出的   事件由子元素传递到父元素的过程,叫做冒泡
捕获事件:网景提出的   事件由父元素到子元素传递的过程,叫做事件捕获

事件代理/事件委托

 利用冒泡机制,将子元素的事件委托给父元素去监听(给父元素添加事件),当子元素触发事件时,事件冒泡到父级如果希望指定的子元素才能触发事件,可以通过事件对象(event)获得事件源(target),然后通过条件判断是不是期望的子元素,如果是的话,执行事件,否则不执行

当事件冒泡跟捕获同时出现的时候先执行哪一个?

先执行事件捕获,后执行事件冒泡,代码如下

 1 <script>
 2 
 3 var oBig = document.getElementById("big");
 4 var oSmall = document.getElementById("small");
 5 
 6 document.addEventListener("click",function(){
 7     alert("我是document---捕获");
 8 },true)
 9 
10 document.addEventListener("click",function(){
11     alert("我是document---冒泡");
12 },false)
13 
14 document.body.addEventListener("click",function(){
15     alert("我是body---冒泡");
16 },false)
17 
18 document.body.addEventListener("click",function(){
19     alert("我是body---捕获");
20 },true)
21 
22 oBig.addEventListener("click",function(){
23     alert("我是oBig---捕获");
24 },true)
25 
26 oBig.addEventListener("click",function(){
27     alert("我是oBig---冒泡");
28 },false)
29 
30 oSmall.addEventListener("click",function(){
31     alert("我是oSmall--捕获");
32 },true)
33 
34 oSmall.addEventListener("click",function(){
35     alert("我是oSmall---冒泡");
36 },false)
37 
38 </script>

当事件冒泡和事件捕获同时出现的时候,先执行事件捕获,再执行事件冒泡。事件捕获是由父元素到子元素的过程,而事件冒泡是由子元素到父元素的过程,所以整体的过程可以看做是一个大写的“V”的过程。一般来说事件冒泡机制,用的更多一些,所以在IE8以及之前,IE只支持事件冒泡。IE9+/FF/Chrome这2种模型都支持,可以通过addEventListener((type, listener, useCapture)的useCapture来设定,useCapture=false代表着事件冒泡,useCapture=true代表着采用事件捕获。

如何组织事件冒泡和事件捕获?

默认情况下,多个事件处理函数会按照DOM事件流模型中的顺序执行。如果子元素上发生某个事件,不需要执行父元素上注册的事件处理函数,那么我们可以停止捕获和冒泡,避免没有意义的函数调用。前面提到的5种事件绑定方式,都可以实现阻止事件的传播。由于第5种方式,是最推荐的做法。所以我们基于第5种方式,看看如何阻止事件的传播行为。IE8以及以前可以通过 window.event.cancelBubble=true阻止事件的继续传播;IE9+/FF/Chrome通过event.stopPropagation()阻止事件的继续传播。

利用事件对象属性:stopPropagation 和 cancelBubble
 
stopPropagetion是一个方法:e.stopPropagetion();
 
cancelBubble的值是一个常量:e.cancelBubble = true;
<script>  
  
    window.onload = function(){  
        var outA = document.getElementById("outA");    
        var outB = document.getElementById("outB");    
        var outC = document.getElementById("outC");    
          
        // 目标  
        outC.addEventListener('click',function(event){  
            alert("target");  
            event.stopPropagation();  
        },false);  
  
        // 事件冒泡  
        outA.addEventListener('click',function(){alert("bubble");},false);  
  
        // 事件捕获  
        outA.addEventListener('click',function(){alert("capture");},true);        
          
    };  
   
</script>  
  
<body>  
    <div id="outA" style="width:400px; height:400px; background:#CDC9C9;position:relative;">  
        <div id="outB" style="height:200; background:#0000ff;top:100px;position:relative;">  
            <div id="outC" style="height:100px; background:#FFB90F;top:50px;position:relative;"></div>   
        </div>  
    </div>  
</body>  

当点击outC的时候,之后打印出capture-->target,不会打印出bubble。因为当事件传播到outC上的处理函数时,通过stopPropagation阻止了事件的继续传播,所以不会继续传播到冒泡阶段。

猜你喜欢

转载自www.cnblogs.com/liming581/p/9048048.html