事件捕获与事件冒泡

时间:2010-04-18 05:10:31

标签: javascript javascript-events

我只想得到普遍的共识,即JS在冒泡和捕获之间更好的事件委派模式。

现在我明白,根据特定的用例,人们可能希望使用捕获阶段而不是冒泡,反之亦然但是我想了解哪种委派模式对于大多数一般情况是优选的以及为什么(对我而言似乎冒泡模式) )。

换句话说,W3C addEventListener实现背后的原因是支持冒泡模式。 [仅当您指定第3个参数及其true时才会启动捕获。但是,你可以忘记第三个参数和冒泡模式被踢了]

我查看了JQuery的bind函数以获得我的问题的答案,它似乎甚至不支持捕获阶段的事件(在我看来,因为IE不支持捕获模式)。

所以看起来冒泡模式是默认选择,但为什么呢?

5 个答案:

答案 0 :(得分:10)

过去这是一个平台问题,Internet Explorer有一个冒泡的模型,而Netscape更多的是关于捕获(但同时支持)。

W3C模型要求您能够选择您想要的那个。

我认为冒泡更受欢迎,因为正如所述,有些平台只支持冒泡...... 它有点作为“默认”模式。

您选择哪一个主要是您正在做的事情和对您有意义的产品。

答案 1 :(得分:7)

在阅读JavaScript:The Definitive Guide,第5版时,我遇到了第422页的示例17-4,它定义了拖动绝对定位元素的函数。在该示例中,函数drag()在文档元素的onmousedown属性中调用。该函数根据鼠标位置的变化重新定位元素,由添加到根文档元素的处理程序查询捕获的mousemove和mouseup事件。他们在文档中捕获这些事件的原因如下:

  

重要的是要注意mousemove和mouseup处理程序被注册为捕获事件处理程序,因为用户可能比文档元素跟随它更快地移动鼠标,并且其中一些事件发生在原始目标元素之外。

这表明在捕获事件时更快速响应的优势。

答案 2 :(得分:2)

This test表明使用捕获而不是冒泡有一点性能优势。即使没有在处理事件时立即杀死事件,但是当它离开时它是微不足道的。我想复杂的DOM会夸大两者之间的性能差异。

答案 3 :(得分:1)

此链接提供了清晰的说明-https://www.quirksmode.org/js/events_order.html

您,Web开发人员,可以选择在捕获阶段还是冒泡阶段中注册事件处理程序。这是通过“高级模型”页面上说明的addEventListener()方法完成的。如果最后一个参数为true,则为捕获阶段设置事件处理程序,如果值为false,则为冒泡阶段设置事件处理程序。

假设你这样做

element1.addEventListener('click',doSomething2,true)
element2.addEventListener('click',doSomething,false)

如果用户单击element2,则会发生以下情况:

click事件在捕获阶段开始。该事件查找element2的任何祖先元素是否具有用于捕获阶段的onclick事件处理程序。 该事件在element1上找到一个。 doSomething2()被执行。 事件向下传播到目标本身,找不到用于捕获阶段的事件处理程序。该事件进入其冒泡阶段并执行doSomething(),该事件已在冒泡阶段注册到element2。 事件再次向上传播,并检查目标的任何祖先元素是否具有用于冒泡阶段的事件处理程序。事实并非如此,因此什么也没有发生。 相反会是

element1.addEventListener('click',doSomething2,false)
element2.addEventListener('click',doSomething,false)

现在,如果用户单击element2,则会发生以下情况:

click事件在捕获阶段开始。该事件将查找element2的任何祖先元素是否具有用于捕获阶段的onclick事件处理程序,而找不到任何事件处理程序。 事件向下传播到目标本身。该事件进入其冒泡阶段并执行doSomething(),该事件已在冒泡阶段注册到element2。 事件再次向上传播,并检查目标的任何祖先元素是否具有用于冒泡阶段的事件处理程序。 该事件在element1上找到一个。现在执行doSomething2()。 与传统模型的兼容性 在支持W3C DOM的浏览器中,传统的事件注册

element1.onclick = doSomething2;

被视为冒泡阶段的注册。

使用事件冒泡 很少有Web开发人员自觉使用事件捕获或冒泡。在当今的网页中,根本没有必要让冒泡事件由多个不同的事件处理程序处理。用户可能会因单击鼠标后发生的几件事而感到困惑,并且通常您希望将事件处理脚本分开。当用户单击某个元素时,会发生某些事情,而当用户单击另一个元素时,会发生其他事情。

当然,将来这可能会改变,因此最好使用可向前兼容的模型。但是,当今事件捕获和冒泡的主要实际用途是默认功能的注册。

答案 4 :(得分:-1)

我不确定,但我很确定你可以用冒泡做的任何事情都可以做到捕捉,反之亦然。

你有一些事件冒泡并且在同一个应用程序中捕获的想法听起来像是让事情变得非常混乱的好方法。我所说的是,我认为冒泡与捕捉并不重要。重要的是你选择一个并坚持下去。

W3C的API通常包含这样的东西,它们具有很多没人真正关心的功能。也许这是优秀默认值如何消除配置甚至整个功能的另一个例子。