JavaScript父子DOM同时绑定捕获与冒泡事件的执行顺序详解

作者:竹影

时间:2026-10-22

浏览:619

本文深入解析JavaScript中父子DOM元素同时绑定捕获与冒泡阶段点击事件的执行顺序。通过原生事件、自定义事件及多事件绑定的实例,阐明W3C标准下的触发逻辑:先捕获后冒泡,同元素按代码顺序执行。文章还涉及自定义事件类型及React中的特殊时序问题,帮助开发者准确控制事件流。

文章目录

引言与问题概述

本文通过具体实例,详细解析在JavaScript中当父子DOM元素同时绑定两个点击事件(分别处于捕获和冒泡阶段)时的执行顺序问题,旨在为读者提供清晰的参考与指导。

事件触发顺序往往令人困惑。当父级与子级元素均绑定了多个事件,且部分事件注册在冒泡阶段、部分在捕获阶段时,具体的触发次序究竟如何?若仅关注此问题的结论,可直接阅读第3部分关于多事件绑定及用户行为触发的内容;若希望深入理解JavaScript事件发生的底层机制,建议通读全文。

原生事件的发生顺序

1. 原生事件的发生顺序

通常情况下,为a标签绑定click事件后,点击该标签会先执行绑定的事件处理函数,随后页面才会跳转。同样,若input元素绑定了blur事件,在输入内容后点击提交按钮,会先触发blur事件,再触发click事件。当然,这仅是普遍情况。笔者曾在React项目中遇到表单提交时先触发click事件而blur事件未及触发的情况,导致表单内容未经校验直接提交至后台。该问题的具体成因至今未明,目前的临时解决方案是在click事件处理函数中增加50ms的延迟。

自定义事件的类型与触发

2. 自定义事件

JavaScript语言本身支持手动触发事件,具体实现代码如下。


a.addEventListener('click', function(){
  console.log(input.value);
  console.log(this.getAttribute('href'));
  console.log(location.href);
}, false); //a是我已经通过id获得好的一个a标签
var event = document.createEvent('HTMLEvents'); // initEvent接受3个参数: 事件类型,是否冒泡,是否阻止浏览器的默认行为
event.initEvent('click', true, true);
event.eventType = 'click';
//触发a上绑定的自定义事件
a.dispatchEvent(event);
//注:jQuery中有更简单的trigger()方法实现自定义事件功能

JavaScript中自定义事件的类型(即document.createEvent('HTMLEvents')方法中的参数)包括:

1. UIEvents:泛指UI相关事件。 2. MouseEvents:泛指鼠标相关事件。 3. MutationEvents:泛指DOM变动事件。 4. HTMLEvents:泛指HTML相关事件。

自定义事件的触发过程相对可控,只要调用dispatchEvent或fireEvent方法,事件即可在指定时刻发生。

父子元素多事件绑定的执行顺序

3. 绑定多个事件,且由用户行为触发

这是最为复杂的情形,也是本文标题所描述的场景:父元素与子元素均绑定了多个事件,且部分事件注册于捕获阶段,部分注册于冒泡阶段。

以下示例中,父级div元素绑定了两个事件(一个位于冒泡阶段,一个位于捕获阶段),子级元素同样如此。我们需要探讨此时事件的触发顺序。


var btn = document.querySelector('button');
var div = document.querySelector('div');
btn.addEventListener('click', function(){
  console.log('bubble','btn');
},false);
btn.addEventListener('click', function(){
  console.log('capture','btn');
},true);
div.addEventListener('click', function(){
  console.log('bubble','div');
},false);
div.addEventListener('click', function(){
  console.log('capture','div');
},true);

执行结果如下:

引言与问题概述

乍看之下结果似乎杂乱无章,但经过仔细分析可以得出明确结论:

对于被直接点击的元素,其绑定的事件严格按照代码书写顺序执行;而对于其他通过冒泡或捕获机制“感知”到事件的其他元素,依据W3C标准,先执行捕获阶段的事件,后执行冒泡阶段的事件。因此,所有事件的完整执行顺序为:其他元素的捕获阶段事件 -> 当前被点击元素的代码顺序事件 -> 其他元素的冒泡阶段事件。

更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《JavaScript事件相关操作与技巧大全》、《JavaScript时间与日期操作技巧总结》、《JavaScript切换特效与技巧总结》、《JavaScript查找算法技巧总结》、《JavaScript动画特效与技巧汇总》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》

希望本文所述内容对大家进行JavaScript程序设计有所帮助。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章