深入理解事件冒泡和事件捕捉

前几天做到阿里的前端面试题,其中的一道选择题考查的知识点就是事件的传播,当时做题的时候不确定答案所以决定总结下这方面的知识点。

首先事件传播分为三个阶段:

第一阶段:发生在目标处理程序调用之前,称为捕获阶段;

第二阶段:目标对象本身的事件处理程序调用;

第三阶段:发生在目标处理程序调用之后,称为冒泡阶段;

回顾历史:两种模型

早期在事件处理顺序上Netscape和微软有两种截然不同不处理方法:

捕获型:Netscape主张事件从最外层开始发生,然后一直向上传播

冒泡型:微软主张事件从目标元素开始发生,然后一直向上传播

后来w3c制定标准规定:任何发生在w3c事件模型中的事件,首是进入捕获阶段,直到达到目标元素,再进入冒泡阶段

事件绑定

程序员可以自己选择绑定事件时采用事件捕获还是事件冒泡,方法就是绑定事件时通过addEventListener函数,它有三个参数,第三个参数若是true,则表示采用事件捕获,若是false,则表示采用事件冒泡。

不过IE9之前的IE不支持addEventListener()和removeEventListener(),IE5之后的版本定义了类似的方法attachEvent()和detachEvent(),但是两者的有如下区别:

1.因为IE事件模型不支持事件捕获,所以attachEvent()和detachEvent()要求只有两个参数:事件类型和处理程序函数。

2.IE方法的第一个参数使用了带"on"前缀的事件处理程序属性名。

3attachEvent()允许相同的事件处理程序函数注册多次,当特定的事件发生时,注册函数的调用次数和注册次数一样。

 <div id="parent">
        <div id="child" href="www.baidu.com">click</div>
    </div>
 var parent = document.getElementById("parent");
        var child = document.getElementById("child");

        parent.addEventListener("click", function(event){
            console.log("parent");
        }, true)//表示parent上面的click事件会在事件捕获的时候处理程序
        child.addEventListener("click", function(event){
            console.log("child");
        });

注意:发生在文档元素上的大部分事件都会冒泡,但是focus blur scroll事件除外。

文档元素上的load事件会冒泡,但它会在Document对象上停止冒泡而不会传播到Window对象,只有当整个文档都加载完毕时才会触发Window对象load事件。


传统的事件绑定:

在一个支持W3C DOM的浏览器中,像这样一般的绑定事件方式,是采用的事件冒泡方式

elem.onclick = doSomething

  <div οnclick="console.log('div')">
        <h1 οnclick="console.log('h1')">click</h1>
    </div>
这段代码在IE8和chrome上都是先打印出h1


取消事件默认操作

通过对象属性或者HTML属性注册的事件处理程序通过返回false取消事件的浏览器默认操作(IE9以上也可以通过调用event.preventDefault())。

通过addEventListener()注册的事件,必须通过调用事件对象的preventDefault()方法取消事件的默认操作。

通过attachEvent()注册的事件,只能通过设置事件对象的returnValue属性为false来取消事件的默认操作。


取消事件传播

在支持事件addEventListener()的浏览器中可以调用时间对象的stopPropagation()方法可以阻止事件传播,该方法可以在事件传播期间的任何时间调用,目标对象上的处理程序依旧被调用,dan'shi

IE9之前由于没有事件捕获所以冒泡是唯一的事件传播,设置事件对象的cancelBubble属性为true

还有一个stopImmediatePropagation()和stopPropagation()相似,区别是它会阻止当前对象上相同事件注册程序调用,stopPropagation方法不会阻止当前元素上的相同事件注册的其他程序。比如:

        parent.addEventListener("click", function(event){
            event.stopImmediatePropagation();
            console.log("parent-first");
        }, true)

        parent.addEventListener("click", function(event){
            console.log("parent-second");
        }, true)
      
        child.addEventListener("click", function(event){
            console.log("child");
        });
上面的代码只打印出parent-first ,注意:如果把event.stopImmediatePropagation()方法parent-second里面则会打印出parent-first和parent-second;

注意:区分取消事件默认行为和取消事件传播的区别






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值