事件捕获和事件冒泡

1.事件冒泡的机制:在元素(标签)嵌套中,如果这些标签都注册了同一个事件,那么在触发内部标签的该事件时,外部标签的该事件也会被触发。事件冒泡这个机制不会触发到内部的元素事件,只会影响到外部的元素事件。这个机制是普遍存在的!

HTML代码

<div id="dv1">
        <div id="dv2">
            <div id="dv3"></div>
        </div>
</div>

CSS代码

        #dv1{
             300px;
            height: 300px;
            background-color: pink;
        }
        #dv2{
             200px;
            height: 200px;
            background-color: skyblue;
        }
        #dv3{
             100px;
            height: 100px;
            background-color: yellow;
        }    

JS代码

var dvObj = [document.getElementById("dv1"),document.getElementById("dv2"),document.getElementById("dv3")];
            function fn2(){                    //一个事件处理函数,在控制台写入触发对象的id    
                    console.log(this.id);
                }
            for (var i = 0; i < dvObj.length; i++) {    //循环注册点击事件

                dvObj[i].addEventListener("click", fn2, false);        
            }

在点击内部盒子时外部的盒子点击事件也会被触发---这就是事件冒泡

2.如何阻止事件冒泡?

    (1).在事件处理函数内部添加 window.event.cancelBubble = true; 用于IE8

    (2).在事件处理函数的形参列表中加入一个参数(事件处理函数默认的参数对象)然后函数内加入 参数名.stopPropagation(); 谷歌、火狐以及现版本大多浏览器

function fn2(e){                    //一个事件处理函数,在控制台写入触发对象的id    
                    console.log(this.id);
                    e.stopPropagation();    //e这个形参是事件处理函数的一个默认参数,e.stopPropagation()这个方法是谷歌和火狐浏览器的阻止冒泡机制的方法
                    // window.event.canceBubble = true;//这是IE8特有的阻止冒泡的方法
                }
            for (var i = 0; i < dvObj.length; i++) {    //循环注册点击事件

                dvObj[i].addEventListener("click", fn2, false);            
            }    

3.

事件触发的三个方式: 1.事件捕获方式 2.事件目标方式 3.事件冒泡方式
事件可以由这三种方式触发,事件捕获方式和事件冒泡方式都基于事件冒泡机制

  • 1.由事件捕获方式触发:由外向内的传递方式触发事件
  • 2.事件目标方式触发:不是由于冒泡机制引发的事件,即事件触发的基点对象,他的事件触发方式为事件目标方式
  • 3.由冒泡方式触发:由内向外的传递方式触发事件

注意:事件触发方式里的冒泡方式和冒泡机制做出区分:事件冒泡机制是一直存在的,不管是设置addEventListener方法里的布尔值为true还是false,都存在冒泡机制,内部元素的事件触发都会引起外部元素的事件触发。冒泡机制的阻止是靠上面2里所述的方法。
事件触发方式的冒泡和捕获只是决定事件触发的先后顺序,可以用设置事件方法里的布尔值来设置。

这里就可以说明addEventListener方法里的布尔值的作用:控制事件处理函数的传递方式:false-事件冒泡方式;true-事件捕获方式

下面设置布尔值为false查看结果:

var dvObj = [document.getElementById("dv1"),document.getElementById("dv2"),document.getElementById("dv3")];
            function fn2(){                    //一个事件处理函数,在控制台写入触发对象的id    
                        console.log(this.id);            
                    }
                for (var i = 0; i < dvObj.length; i++) {    //循环注册点击事件

                    dvObj[i].addEventListener("click", fn2, false);            
                }    
        //点击内部盒子,输出结果为dv3,dv2,dv1;可以看出里面的盒子的事件先触发,由冒泡方式内向外依次触发冒泡机制引发的事件
        

下面设置布尔值为true查看结果:

var dvObj = [document.getElementById("dv1"),document.getElementById("dv2"),document.getElementById("dv3")];
        function fn2(){                    //一个事件处理函数,在控制台写入触发对象的id    
                    console.log(this.id);            
                }
            for (var i = 0; i < dvObj.length; i++) {    //循环注册点击事件

                dvObj[i].addEventListener("click", fn2, true);            
            }    
        //点击内部盒子,输出结果为dv1,dv2,dv3;可以看出外面的盒子的事件先触发,由捕获方式由外向里依次触发冒泡机制引发的事件

可以利用:事件处理参数.eventPhase查看事件触发的方式:1为事件捕获,2为事件目标,3为事件冒泡

var dvObj = [document.getElementById("dv1"),document.getElementById("dv2"),document.getElementById("dv3")];
        function fn2(e){                        
                    console.log(this.id + "触发方式为" + e.eventPhase);            
                }
            for (var i = 0; i < dvObj.length; i++) {    

                dvObj[i].addEventListener("click", fn2, true);            
            }    

点击内部盒子结果为:

           dv1触发方式为1
           dv2触发方式为1
           dv3触发方式为2

可以看出这是捕获方式,dv1先触发,然后向内,dv2也是捕获方式,再向内到达目标元素,为目标方式

将true改成false同理,可以看出除目标元素之外其他元素的触发是冒泡方式

原文地址:https://www.cnblogs.com/yucheng6/p/9671741.html