1

大家好,我是IT修真院成都分院第09期学员,一枚正直纯洁善良的web程序员。今天给大家分享一下,修真院官网js任务4,IE事件流和W3C事件流有什么区别,参数分别是什么,以及如何阻止事件冒泡?

1.背景介绍

一、事件流

事件,是文档或浏览器窗口中发生的一些特定的交互瞬间。事件流,描述的是页面中接受事件的顺序。IE9,chrome,Firefox,Opera,Safari均实现了DOM2级规范中定义的标准DOM事件,而IE8和IE8以下版本仍然保留专有的事件处理方式。

事件冒泡:

事件冒泡是由IE开发团队提出来的,即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播。

clipboard.png

clipboard.png

clipboard.png

点击div,将先输出“div”,再输出“body”。

IE9,chrome,Firefox,Opera,Safari都支持事件冒泡,并将事件冒泡到window对象。

事件捕获

事件捕获是由Netscape Communicator团队提出来的,是先由最上一级的节点先接收事件,然后向下传播到具体的节点。当用户点击了

元素,采用事件捕获,则click事件将按照

document—>html—>body—>div 的顺序进行传播。

若在div和body上都定义了click事件,如下:

clipboard.png

点击div,将先输出“body”,再输出“div”。

IE9,chrome,Firefox,Opera,Safari都支持事件捕获,但是IE8和IE8以下的版本只支持事件冒泡。尽管DOM2规范要求事件应该从document对象开始传播,但是现在的浏览器实现都是从window对象开始捕获事件。

二.知识剖析

DOM事件流

"DOM2级事件”规定的事件流包含三个阶段:

(1)事件捕获阶段,

(2)处于目标阶段

(3)事件冒泡阶段。

首先发生的是事件捕获,然后是实际的目标接收到事件,最后阶段是冒泡阶段。以上面为例,单击

元素将按照下图触发事件:

clipboard.png

若在div和body上都定义了click事件,如下:

clipboard.png

点击div,将先输出“event catch”,再输出“div”,最后输出“event bubble”。

DOM2级事件处理程序

IE9,chrome,Firefox,Opera,Safari均实现了DOM2级事件处理程序,绑定事件方法addEventListener()接收三个参数:事件名称,事件处理函数和一个布尔值。布尔值为true,则表示在捕获阶段调用事件处理程序;如果为false,则表示在冒泡阶段调用事件处理程序。

addEventListener允许在同一个元素上添加多个事件处理程序,如下所示:

clipboard.png

先输出“event bubble”,后输出“event catch”。

在目标对象上同时绑定捕获阶段/冒泡阶段事件处理程序,触发目标对象时属于DOM事件流中的目标阶段。目标阶段事件的执行顺序:先注册的先执行,后注册的后执行。也就是说,在目标对象上绑定的函数是采用捕获,还是采用冒泡,都没有什么关系,因为冒泡和捕获只是对父元素上的函数执行顺序有影响,对自己没有什么影响。

删除DOM2级事件处理程序,采用removeEventListener(),删除时传入的参数必须和绑定时传入的参数相同,不能传入匿名函数。如下所示:

clipboard.png

总结:

先按由上往下的顺序执行事件捕获的执行程序,再执行目标元素的执行程序,最后按由下往上的顺序执行冒泡事件。代码如下所示:

clipboard.png

输出顺序:body:event catch—>parent:event catch—>child—>parent:event bubble—>body:event bubble

三.常见问题

阻止事件冒泡和捕获

四.解决方案

默认情况下,多个事件处理函数会按照DOM事件流模型中的顺序执行。如果子元素上发生某个事件,不需要执行父元素上注册的事件处理函数,那么我们可以停止捕获和冒泡,避免没有意义的函数调用。IE8以及以前可以通过 window.event.cancelBubble=true阻止事件的继续传播;IE9+/FF/Chrome通过event.stopPropagation()阻止事件的继续传播。

clipboard.png

当点击outC的时候,之后打印出capture-->target,不会打印出bubble。因为当事件传播到outC上的处理函数时,通过stopPropagation阻止了事件的继续传播,所以不会继续传播到冒泡阶段。

clipboard.png

执行结果是只打印capture,不会打印target和bubble。虽然点击了outC,但是却没有触发outC上的事件处理函数,而是触发了outA上的事件处理函数。

五.编码实战

六.扩展思考

如何做到事件委托?

7.参考文献

参考1:javaScript事件(一)事件流

参考2:js之事件冒泡和事件捕获详细介绍

8 更多讨论

鸣谢

感谢 郭婷婷 师姐,此教程是在他们之前技术分享的基础上完善而成

感谢大家观看

PPT链接

视频链接

今天的分享就到这里啦,欢迎大家点赞、转发、留言、拍砖~

我们下周再见!


用户bPbdDlb
422 声望36 粉丝