小兔网

浅谈JavaScript中的事件冒泡和事件捕获

相关推荐:《javascript视频教程

JS事件流原理图:

1005354-20161222125521823-1914047378[1]

由此可知道,一个完整的JS事件流是从window开始,最后回到window的一个过程;事件流被分为三个阶段:捕获过程(1~5)、目标过程(5~6)、冒泡过程(6~10);

事实上,捕获过程和冒泡过程是完全相反的过程,即事件由父元素向子元素传播和子元素向父元素传播的过程。

事件捕获

事件捕获在事件绑定的第二种形式下才能实现

<!DOCTYPE html><html><head>    <meta charset="UTF-8">    <title>事件捕获</title>    <style>        div{padding:40px;}        #div1{            background: red;        }        #div2{            background:green;        }        #div3{background: blue;}    </style>    <script>        window.onload=function(){            var oDiv1=document.getElementById('div1');            var oDiv2=document.getElementById('div2');            var oDiv3=document.getElementById('div3');            function fn1(){                alert(this.id);            }            //点击div3部分时,分别弹出div1,div2,div3            oDiv1.addEventListener('click',fn1,true);//为true时,是事件捕获   false=冒泡            oDiv2.addEventListener('click',fn1,true);            oDiv3.addEventListener('click',fn1,true);        }    </script></head><body><div id="div1">    <div id="div2">        <div id="div3"></div>    </div></div></body></html>

上面例子中,点击p3时,p1会接收到两个点击事件,一个是在捕获阶段触发了p1的点击事件,一个是在冒泡阶段触发了p1的点击事件;addEventListener中的第三个参数:true----捕获,false-----冒泡;上面设置为true即捕获阶段的点击事件被触发了

注:p1会接收到两个点击事件与是否触发该事件无关

再来个例子:

<!DOCTYPE html><html><head>    <meta charset="UTF-8">    <title>事件捕获</title>    <style>        div{padding:40px;}        #div1{            background: red;        }        #div2{            background:green;        }        #div3{background: blue;}    </style>    <script>        window.onload=function(){            var oDiv1=document.getElementById('div1');            var oDiv2=document.getElementById('div2');            var oDiv3=document.getElementById('div3');                                oDiv1.addEventListener('click',function(){                alert(1);            },false);            oDiv1.addEventListener('click',function(){                alert(3);            },true);            oDiv3.addEventListener('click',function(){                alert(2);            },false);            //点击div3,分别弹出3,2,1        }    </script></head><body><div id="div1">    <div id="div2">        <div id="div3"></div>    </div></div></body></html>

点击p3,查看弹出的结果分别是:3、2、1

点击p3时,p1会接收到两个点击事件,在捕获阶段(true),触发了p1的点击事件,弹出结果:3;在冒泡阶段,触发了p3的点击事件,弹出结果:2,然后触发了p1的点击事件,弹出结果:1

事件冒泡

当一个元素接受到事件的时候,会把它接收到的所有事件传播给它的父级,一直到顶层window,叫事件冒泡机制;

例子:

<!DOCTYPE html><html><head>    <meta charset="UTF-8">    <title>事件冒泡</title>    <style>        div{padding:40px;}       #div1{           background: red;       }       #div2{           background:green;       }        #div3{background: blue;}    </style>    <script>        window.onload=function(){            var oDiv1=document.getElementById('div1');            var oDiv2=document.getElementById('div2');            var oDiv3=document.getElementById('div3');            function fn1(){                alert(this.id);            }            //事件函数绑定            oDiv1.onclick=fn1;//告诉div1,如果它接收到了一个点击事件,那它就去执行fn1            oDiv2.onclick=fn1;            oDiv3.onclick=fn1;//div3,div1 事件冒泡        }    </script></head><body><div id="div1">    <div id="div2">        <div id="div3"></div>    </div></div></body></html>

阻止冒泡:在当前要阻止冒泡的事件函数中调用event.cancelBubble=true;

<!DOCTYPE html><html><head>    <meta charset="UTF-8">    <title>阻止冒泡</title>    <style>        #div1{            width:100px;            height:200px;            border:1px solid red;            display: none;        }    </style>    <script>        window.onload=function(){            var oBtn=document.getElementById('btn1');            var oDiv=document.getElementById('div1');            oBtn.onclick=function(ev){                var oEvent=ev||event;                //阻止当前事件函数事件冒泡                oEvent.cancelBubble=true;                oDiv.style.display='block';            }            document.onclick=function(){               /* setTimeout(function(){//观察事件冒泡:div出现一秒钟后隐藏了                    oDiv.style.display='none';                },1000);*/                oDiv.style.display='none';            }        }    </script></head><body><input type="button" value="按钮" id="btn1"><div id="div1">点击按钮div就出现,点击除按钮以外的部分div就消失</div></body></html>

对比没有取消冒泡事件时的效果,下面用了延时器一遍观察效果

事件冒泡的运用

下面是一个网站中常见的功能——分享到

<!DOCTYPE html><html><head>    <meta charset="UTF-8">    <title>事件冒泡</title>    <style>        #div1{            width:100px;            height:200px;            background: red;            position: absolute;            left:-100px;            top:100px;        }        #div2{            width:30px;            height:60px;            position: absolute;            right:-30px;            top:70px;            background:#000000;            color:#ffffff;            text-align: center;        }    </style>    <script>        window.onload=function(){            var oDiv=document.getElementById('div1');            oDiv.onmouseover=function(){                this.style.left=0+'px';//鼠标移动到div2时,div2接收到over、out事件时它自己不做,传播给父级div1执行            }            oDiv.onmouseout=function(){                this.style.left=-100+'px';            }        }    </script></head><body><div id="div1">    <div id="div2">分享到</div></div></body></html>

更多编程相关知识,请访问:编程视频!!

以上就是浅谈JavaScript中的事件冒泡和事件捕获的知识。速戳>>知识兔学习精品课!