事件流:阻止事件冒泡、阻止事件捕获preventDefault()、stopPropagation()、return false 之间的区别

参考文章:https://www.jb51.net/article/94394.htm


W3C 中定义事件的发生经历三个阶段:

捕获阶段(capturing)、目标阶段(targetin)、冒泡阶段(bubbling)

  • 冒泡型事件:当你使用事件冒泡时,子级元素先触发,父级元素后触发
  • 捕获型事件:当你使用事件捕获时,父级元素先触发,子级元素后触发
  • DOM事件流:同时支持两种事件模型:捕获型事件和冒泡型事件

阻止事件发生的方法:

  • 阻止冒泡:在W3c中,使用 stopPropagation() 方法;在IE下设置 cancelBubble = true
  • 阻止捕获:阻止事件的默认行为,例如 click - <a> 后的跳转。在W3c中,使用 preventDefault() 方法,在 IE 下设置 window.event.returnValue = false

再谈事件函数执行先后顺序:

利用 addEventListener() 在元素上绑定多个事件,且设置不同的事件流。也就是说,先后绑定两个click 事件,一个设置事件冒泡,一个设置事件捕获

我们在outC上触发onclick事件(这个是目标对象),如果我们在outC上同时绑定捕获阶段/冒泡阶段事件处理函数会怎么样呢?

<script>
 
 window.onload = function(){
        var outA = document.getElementById("outA");
        var outB = document.getElementById("outB");
        var outC = document.getElementById("outC");

        // 目标(自身触发事件,是冒泡还是捕获无所谓)
        outC.addEventListener('click',function(){console.log("target2");},true);
        outC.addEventListener('click',function(){alert("target1");},true);

        // 事件冒泡
        outB.addEventListener('click',function(){alert("bubble2");},false);
        outA.addEventListener('click',function(){alert("bubble1");},false);

        // 事件捕获
        outB.addEventListener('click',function(){alert("capture2");},true);
        outA.addEventListener('click',function(){alert("capture1");},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的时候,打印顺序是:capture1-->capture2-->target2-->target1-->bubble2-->bubble1。

捕获事件最后才绑定 ,但是最先执行了;然后是目标阶段的事件;最后是冒泡事件。

捕获事件 --> 目标阶段 --> 冒泡事件

由于outC是我们触发事件的目标对象,在outC上注册的事件处理函数,属于DOM事件流中的目标阶段。目标阶段函数的执行顺序:先注册的先执行,后注册的后执行。这就是上面我们说的,在目标对象上绑定的函数是采用捕获,还是采用冒泡,都没有什么关系,因为冒泡和捕获只是对父元素上的函数执行顺序有影响,对自己没有什么影响。如果不信,可以将下面的代码放进去验证。

// 目标(自身触发事件,是冒泡还是捕获无所谓)
    outC.addEventListener('click',function(){console.log("target1");},false);
    outC.addEventListener('click',function(){console.log("target2");},true);
    outC.addEventListener('click',function(){console.log("target3");},true);
    outC.addEventListener('click',function(){console.log("target4");},false);

至此我们可以给出事件函数执行顺序的结论了:捕获阶段的处理函数最先执行,其次是目标阶段的处理函数,最后是冒泡阶段的处理函数。目标阶段的处理函数,先注册的先执行,后注册的后执行。

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值