js基础之冒泡和捕获机制

DOM事件所囊括的知识较为庞杂,本片文章总结一下冒泡和捕获机制到底是怎么运作的。

事件流

当我们点击页面上的一个按钮的时候,是按钮最外层的父元素先收到事件并执行,还是这个被我们点击的按钮先收到事件并执行?所以这儿引入了事件流的概念:事件流所描述的就是从页面中接受事件的顺序。(其实挺起来还是一脸懵懂的!没错我当时就是这样子的。)
事件流也有两种,分别是事件冒泡和事件捕获,现行的主流是事件冒泡。下面一一来说:

1、事件冒泡
时间冒泡就是从我们上面提到的被我们点击的那个按钮开始,先执行按钮上绑定的事件,执行完之后,继续往按钮的父元素执行父元素上绑定的事件。
看这个简单的代码:

<div id="div1">
        div1
    <div id="div2">
                div2
        <div id="div3">
                    div3
        </div>
    </div>
</div>

div中嵌套了两个div,js代码:

var div1 =document.getElementById('div1');
var div2 =document.getElementById('div2');
var div3 =document.getElementById('div3');
    div2.addEventListener('click',function(){
       alert('div2');
     },false);
    div1.addEventListener('click',function(){
       alert('div1');
     },false);
    div3.addEventListener('click',function(){
       alert('div3');
     },false);

注意:addEventListener这个方法的第三个参数选false,为冒泡事件,如果是true为我们后面讲的捕获事件。这里我们运行的输出为:
这里写图片描述

当我点击div3的时候,会依次弹出div3,div2,div1。当我点击div2的时候,会依次弹出div2,div1。当我点击div1的时候,只弹出div1。
这个结果说明,事件冒泡是从我们当前点击到的那个div开始的,然后不断往父元素冒泡。
2、事件捕获
其实很简单,我们只要把上面的代码中的false改为true:

 var  div1 =document.getElementById('div1');
 var  div2 =document.getElementById('div2');
 var  div3 =document.getElementById('div3');
      div2.addEventListener('click',function(){
        alert('div2');
      },true);
      div1.addEventListener('click',function(){
        alert('div1');
      },true);
      div3.addEventListener('click',function(){
        alert('div3');
      },true);

这样我们点击div3的时候,会依次弹出div1,div2,div3。当我们点击div2的时候依次弹出div1,div2。当点击div1的时候,只弹出div1。这就是所谓的事件捕获。
总结:事件捕获跟冒泡方向是相反的。

这个时候你要问了,如果三个addEventListener中有第三个参数有false又有true怎么办?会不会打架?撞车?呵呵,当然不会。其中是有规则的,W3C明智地在这场争斗中选择了一个折中的方案:任何发生在w3c事件模型中的事件,首是进入捕获阶段,直到达到目标元素,再进入冒泡阶段。(w3c作为交警指挥了这个杂乱的交通)
当我们把代码改成:

var div1 =document.getElementById('div1');
var div2 =document.getElementById('div2');
var div3 =document.getElementById('div3');
    div1.addEventListener('click',function(){
        alert('div1');
      },true);
    div2.addEventListener('click',function(){
        alert('div2');
      },false);
    div3.addEventListener('click',function(){
        alert('div3');

这样子三个div就有冒泡又有捕获,这个时候
我们点击div3的时候,依次弹出div1、div3、div2;
点击div2的时候弹出次序为div1、div2。
分析:(认真看一下这个分析,如果有不准确的麻烦告诉宝宝一声,谢谢)
这三个div有捕获又又冒泡,根据交警w3c的规则,先找捕获的,也就是div1,所以当我们点击div3的时候,先执行的是div1上的点击事件,div1执行完了往外走,看看还有没有那个div是捕获的,发现没有了,那么此时就开始寻找冒泡的。冒泡的顺序是从最外一层的div开始往里面走的,所以此时就找到了div3,执行完div3上的绑定事件之后就往父元素中找,发现诶有div2也是冒泡的哦!果断执行了div2的事件。所以,最后的弹出顺序就是div1–>div3–>div2。
到此我们应该都明白了其中的规律的吧!要是把代码改成这样:


var div1 =document.getElementById('div1');
var div2 =document.getElementById('div2');
var div3 =document.getElementById('div3');
    div1.addEventListener('click',function(){
        alert('div1');
      },false);
    div2.addEventListener('click',function(){
        alert('div2');
      },true);
    div3.addEventListener('click',function(){
        alert('div3');
      },false);

大家应该都猜得到执行结果了吧!我不会告诉你们是div2–>div3–>div1

总结:
冒泡是从目标元素往父元素走,捕获是从祖宗元素开始往目标元素走;两个都有的话先捕获再冒泡。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值