事件冒泡/捕获 - 它从哪里开始/结束?

Posted

技术标签:

【中文标题】事件冒泡/捕获 - 它从哪里开始/结束?【英文标题】:Event bubbling/capturing - where does it start/end? 【发布时间】:2012-09-16 13:36:39 【问题描述】:

我知道一个事件有两种模式——冒泡和捕获。

当一个事件设置为冒泡时,javascript 是否会检查“文档”?

当一个事件设置为捕获时,Javascript是否总是从“文档”开始?

Javascript 如何知道在哪里停止/开始?

假设我的 body 标签中有以下代码。

<div id='outer'>
    <div id='inner'></div>
</div>

当我将事件设置为#inner 以冒泡时,Javascript 是检查文档还是停止在 #outer

【问题讨论】:

来自 quirksmode 的内容丰富的文章:quirksmode.org/js/events_order.html @techfoobar // 我确实读过那篇文章,但不清楚 Javascript 是检查文档还是停止在父元素。 如果它停在外层,它怎么知道document.body或类似文件上是否有任何事件监听器? @JohnKurlak // 我猜 Javascript 维护了一个事件列表或类似的东西。 阅读 W3Cs DOM Events 了解事件如何工作的规范。 【参考方案1】:

来自 W3C Document Object Model Events

我知道我在吹毛求疵,但处理您描述的事件的不是 javascript,而是 DOM 引擎(文档对象模型)。在浏览器中,javascript 和 DOM 引擎之间存在绑定,因此可以将事件传播到 javascript,但不限于 javascript。例如 MSIE 支持 BASIC。

当一个事件设置为冒泡时,Javascript 是否会检查“文档”?

1.2.3"这种向上传播将持续到并包括文档"

“任何事件处理程序都可以选择通过调用 Event 接口的 stopPropagation 方法来阻止进一步的事件传播。如果任何 EventListener 调用此方法,则当前 EventTarget 上的所有其他 EventListener 都将被触发,但在该级别将停止冒泡”

当一个事件设置为捕获时,Javascript是否总是从“文档”开始?

1.2.2“捕获从树的顶部开始,通常是文档,”

【讨论】:

【参考方案2】:

事件冒泡

JavaScript 一直检查到文档。如果您在文档上添加一个侦听器,在内部添加一个侦听器,则两个侦听器都会触发。

事件捕获

JavaScript 从文档开始,一直到内部。如果您在文档上添加一个侦听器,在内部添加一个侦听器,则两个侦听器都会触发。 我的发现

原来浏览器做了某种智能处理,所以它

a) 不必遍历整个父层次结构

b) 不必遍历所有事件。 证明

a) 当点击内部 div 时,浏览器没有时间触发两个点击事件:

Fiddle

b) 当存在许多附加到不在父层次结构中的其他 DOM 元素的其他事件时,当点击内部 div 时,浏览器不会花时间触发两个点击事件:

Fiddle

【讨论】:

事件冒泡 // 即使文档没有事件?【参考方案3】:

部分回答..

1 - 当事件设置为冒泡时,Javascript 是否会检查“文档”?

如果层次结构中的元素之一决定通过调用 stopPropagation() 来停止冒泡

【讨论】:

以上是关于事件冒泡/捕获 - 它从哪里开始/结束?的主要内容,如果未能解决你的问题,请参考以下文章

事件绑定,事件捕获,事件冒泡以及事件委托,兼容IE

JS中的事件冒泡和事件捕获

捕获冒泡

事件冒泡 事件捕获 事件委托

js 事件冒泡与事件捕获

JavaScript 事件冒泡,事件捕获,事件委托