JS事件流为什么要设计成三个阶段以及如何确认传播路径?

文章链接:https://segmentfault.com/a/11...
原文:http://codepen.io/zhaojun/pos...

js事件流有三个众所周知的阶段:捕获命中冒泡。关于事件流有三个问题:

  1. 为什么要设计成三个阶段?

    有些地方是讲的:因为历史原因——N公司提倡捕获,M公司提倡冒泡,两个公司互不妥协,于是标准组织干脆兼容两者,让事件跑一个来回,倘若不支持某个过程则静默出进入相关阶段就好。久而久之,大家都认了这个规则,但是实际上来说让事件跑一个来回效率上肯定是不高的,而且从我的理解来看只进行捕获或者冒泡也是合乎逻辑的。所以为什么现代浏览器(比如chrome)要同时支持两种传播方式呢?

  2. 传播路径如何确定?

    上文中说到事件在传播前,浏览器会先为其计算出传播路径,然而DOM树表面上看并不是一棵查找二叉树,只是一种描述层级关系的树状数据结构。那么假设浏览器从操作系统拿到了事件的基本信息(点击位置,哪个键位,发生时间等),浏览器怎么在这样的树状结构中查找出一条确定的路径呢?遍历当然是可以的,但是这样效率是否太低?如果每个元素都有一个独一无二的ID,对这个路径查找问题有帮助吗?

  3. 事件与其它过程如何交互?

    问题可能说的有点抽象,假设我们在div元素上绑定了一个hover动画,那么当鼠标划过时需要发生两件事情:展示动画和触发mouseover事件。我觉得合理的设计应该是先触发动画再触发事件,有两种可能性:

    • 浏览器在事件传播前触发动画,无论是捕获还是冒泡,对动画触发先后没有影响;

    • 浏览器在在事件传播过程中触发动画,那么动画触发顺序可能和采用捕获还是冒泡有关系;

请不吝赐教。

阅读 5.3k
1 个回答

说说对1,3两个问题的一点个人看法。

第1个问题:

为什么要有冒泡和捕获,自然各自有各自的应用场景。比如有parent,child两个父级关系的div。我在child上点击,但是我只想让child接收这个事件,那么需要用到的是冒泡机制,用捕获机制是没办法处理这个问题的,因为捕获的话肯定得先经过parent,所以你如果在parent绑定了事件,自然也就触发了。而如果我只想想parent处理这个事件,不想child去处理,那么就需要用到捕获机制。用冒泡的话,事件先到达child,自然是不行的。所以设计两种事件触发机制,来源于应用场景的需要。随便提一下,这不是浏览器标准,应该是W3C的标准就是这么说的。

第3个问题:

合理的设计应该是先触发动画再触发事件

我感觉先触发事件才是正确的,理由与浏览器渲染机制基本相同,JS可能会对dom进行各种修改,先渲染再执行JS,很大可能会渲染两次,这是没有必要的。动画与此类似

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏