深入理解JavaScript的事件冒泡与事件捕获
前言
JavaScript中提供了很多操作DOM的API。
事件冒泡和事件捕获是指浏览器中处理DOM元素上事件的两种不同方式。事件冒泡和事件捕获都是JavaScript事件模型中的一部分,可以用来处理事件。
对于这个问题,在实际开发中,并不是非常重要,因为在工作中我们基本上不会直接操作DOM,为了高效一般都是通过Vue、React这些框架,所以关于事件处理程序的一些坑直接就被避免了!!!
但是,多了解一点是没有坏处的,毕竟面试会考~
一、事件冒泡
事件冒泡(Event Bubbling)是指当一个元素触发了某个事件时,该事件会从最具体的元素开始逐级向上传播到较为不具体的元素(也就是从子元素向父元素方向传播),直到传播到文档的根节点为止。这种传播方式就像气泡从水底冒出水面一样,所以叫做事件冒泡。

举个例子,假设有一个包含两个嵌套 div 元素的 HTML 结构如下:
<div id="outer"><div id="inner"><button>点击我</button></div>
</div>当我们在按钮上点击时,事件会按照如下顺序进行冒泡:
首先,按钮元素触发点击事件。
然后,该事件会从最具体的元素(按钮元素)开始向外传播到其父元素(内部 div 元素)。
接着,该事件继续向外传播到外部 div 元素。
最后,该事件传播到文档的根节点(HTML 元素)。
在这个过程中,每个元素都可以在自己的事件处理程序中处理该事件。这意味着,当点击按钮时,除了按钮本身的事件处理程序之外,内部 div 和外部 div 元素也可以捕获并处理该事件。
可以通过 JavaScript 的 Event 对象来阻止事件冒泡。例如,可以使用 event.stopPropagation() 方法来阻止事件继续向外传播。
二、事件捕获
事件捕获(Event Capturing)是一种处理事件的方式,与事件冒泡相反。事件捕获从文档根节点开始,逐级向下传播到最具体的元素,也就是从父元素向子元素方向传播。

与事件冒泡不同,事件捕获在元素本身触发事件之前被触发。具体来说,事件会从文档根节点开始向下传播,直到达到触发该事件的最具体的元素。这个过程中,每个元素都可以在自己的事件处理程序中处理该事件。
还是刚才的例子
<div id="outer"><div id="inner"><button>点击我</button></div>
</div>当我们在按钮上点击时,事件会按照如下顺序进行捕获:
首先,该事件从文档的根节点开始向下传播到最外层的元素(外部 div 元素)。
然后,该事件继续向下传播到内部的 div 元素。
最后,该事件传播到触发该事件的最具体的元素(按钮元素)。
在这个过程中,每个元素都可以在自己的事件处理程序中处理该事件。这意味着,当点击按钮时,除了按钮本身的事件处理程序之外,内部 div 和外部 div 元素也可以捕获并处理该事件。
可以通过 JavaScript 的 Event 对象来阻止事件捕获。例如,可以使用 event.preventDefault() 方法来阻止事件的默认行为,也可以使用 event.stopPropagation() 方法来阻止事件继续向下传播。
三、事件处理程序
事件处理程序指的是一段程序代码,它用于响应特定事件的发生。在计算机编程中,事件通常是指用户与程序交互的某个动作,例如点击鼠标、按下键盘键或者在窗口中拖拽对象等。事件处理程序可以是一个函数、方法或者一段程序代码片段,当特定事件发生时,它将被执行。
事件流和事件处理程序是密切相关的概念,事件流定义了事件在程序中的传播方式,而事件处理程序则是用于响应这些事件的程序代码。
JavaScript的事件流
大致可以分成3种:
DOM0事件流
DOM2事件流
IE事件流

DOM0 事件流
当一个事件发生时,它首先在捕获阶段被处理,然后在冒泡阶段被处理。捕获阶段是从根节点到目标节点的过程,冒泡阶段则是从目标节点到根节点的过程。在 DOM0 事件流中,只有在冒泡阶段才会处理事件处理程序。
DOM2 事件流
与 DOM0 事件流不同,DOM2 事件流允许在捕获阶段和冒泡阶段都可以处理事件处理程序。这种事件流的好处在于可以更灵活地控制事件处理的顺序。
IE 事件流
IE 事件流与 DOM2 事件流类似,但是在捕获阶段和冒泡阶段的顺序相反,即从目标元素到根元素的捕获阶段,然后是从根元素到目标元素的冒泡阶段。
DOM2 事件流相对于 DOM0 事件流和 IE 事件流更加灵活和可控,因此是更好的选择。不过,为了保证跨浏览器的兼容性,通常需要在事件处理程序中同时使用捕获和冒泡两个阶段。
DOM0、DOM2和IE事件有什么区别?
DOM0和DOM2是两个不同版本的DOM事件模型,而IE事件模型是一种与DOM事件模型不同的事件模型。
DOM0事件模型指的是最初的DOM事件模型,它是在1998年定义的。在DOM0事件模型中,事件处理程序直接被添加到HTML元素的属性中,例如:
<button onclick="alert('Hello world!')">Click me</button>在这个例子中,点击按钮时,将弹出一个警告框,因为事件处理程序直接在按钮元素的onclick属性中定义。
DOM2事件模型是一个更加现代的事件模型,它是在2000年定义的。在DOM2事件模型中,事件处理程序通过addEventListener()方法添加到HTML元素上,例如:
document.querySelector('button').addEventListener('click', function() {alert('Hello world!');
});在这个例子中,点击按钮时,将弹出一个警告框,因为事件处理程序通过addEventListener()方法添加到按钮元素上。
与DOM事件模型不同,IE事件模型使用attachEvent()方法将事件处理程序添加到HTML元素上,例如:
document.querySelector('button').attachEvent('onclick', function() {alert('Hello world!');
});在这个例子中,点击按钮时,将弹出一个警告框,因为事件处理程序通过attachEvent()方法添加到按钮元素上。
DOM0事件模型和IE事件模型的主要区别在于事件处理程序的添加方式,而DOM2事件模型引入了更多的功能,如事件捕获和事件冒泡,并且可以同时添加多个事件处理程序。
哪一种模型更好?
在现代Web开发中,推荐使用DOM2事件模型,因为它提供了更多的功能和灵活性,可以更好地控制和管理事件。以下是一些使用DOM2事件模型的优点:
支持事件捕获和事件冒泡。事件捕获和事件冒泡是DOM2事件模型的核心特性之一,使得事件处理程序能够在DOM树中不同的层级进行注册,从而更好地控制事件的传播和处理。
可以同时添加多个事件处理程序。通过addEventListener()方法,可以为同一个事件添加多个事件处理程序,而不会覆盖先前添加的事件处理程序。
可以从HTML元素上删除事件处理程序。使用removeEventListener()方法可以方便地从HTML元素上删除事件处理程序,而不必像DOM0事件模型那样通过将事件处理程序设置为null来达到删除的效果。
支持事件对象。在DOM2事件模型中,事件处理程序会接收一个事件对象作为参数,该事件对象包含有关事件的详细信息,例如事件类型、事件目标、鼠标位置等,从而能够更好地处理和控制事件。
综上所述,DOM2事件模型是一种功能更强大、更灵活的事件模型,相比于DOM0事件模型和IE事件模型更加推荐使用。
四、两者能干什么?
使用事件冒泡和事件捕获可以实现:
事件委托:可以将事件处理程序绑定到父元素而不是子元素上。当子元素触发该事件时,事件将沿着冒泡路径传递到父元素,由父元素的事件处理程序进行处理。这样可以减少事件处理程序的数量,提高性能和可维护性。
事件拦截:通过在事件处理程序中调用 event.stopPropagation() 方法,可以阻止事件继续传播,从而避免不必要的事件触发和处理。
多个事件处理程序的执行顺序控制:通过在捕获或冒泡阶段注册事件处理程序,并控制其在事件传播路径上的位置,可以控制多个事件处理程序的执行顺序。
总之,了解和使用事件冒泡和事件捕获可以帮助我们更好地处理 HTML 和 JavaScript 中的事件,提高代码的可维护性和性能。
相关文章:
深入理解JavaScript的事件冒泡与事件捕获
前言JavaScript中提供了很多操作DOM的API。事件冒泡和事件捕获是指浏览器中处理DOM元素上事件的两种不同方式。事件冒泡和事件捕获都是JavaScript事件模型中的一部分,可以用来处理事件。对于这个问题,在实际开发中,并不是非常重要,…...
格密码学习笔记(六):格中模运算
文章目录格中取模运算CVP和格的陪集致谢格中取模运算 定义(格的基本区域) P⊂Rn:{Px∣x∈L}\mathcal{P} \subset \mathbb{R}^n : \{ \mathcal{P} \bm{x} | \bm{x} \in \mathcal{L} \}P⊂Rn:{Px∣x∈L}是Rn\mathbb{R}^nRn的一种划分。 用P\mathcal{P}P对…...
【C++】非常重要的——多态
凡是面向对象的语言,都有三大特性,继承,封装和多态,但并不是只有这三个特性,是因为者三个特性是最重要的特性,那今天我们一起来看多态! 目录 1.多态的概念 1.1虚函数 1.2虚函数的重写 1.3虚…...
发票账单很多?python助你批量完成数据提取
每天面对成堆的发票,无论是税务发票还是承兑单据,抑或是其他各类公司数据要从照片、PDF等不同格式的内容中提取,我们都有必要进行快速办公的能力提升。因此,我们的目标要求就十分明显了,首先要从图片中获取数据&#x…...
[闪存2.1] NAND FLASH特性串烧 | 不了解闪存特性,你能用好闪存产品吗?
前言 为了利用好闪存, 发挥闪存的优势, 以达到更好的性能和使用寿命, 那自然要求了解闪存特性。 闪存作为一种相对较新的存储介质, 有很多特别的特性。 一.闪存的特性 凡是采用Flash Memory的存储设备,可以统称为闪存存储。我们经常谈的固态硬盘(SSD),可以由volatile/…...
面试官问我按钮级别权限怎么控制,我说v-if,面试官说再见
最近的面试中有一个面试官问我按钮级别的权限怎么控制,我说直接v-if啊,他说不够好,我说我们项目中按钮级别的权限控制情况不多,所以v-if就够了,他说不够通用,最后他对我的评价是做过很多东西,但…...
阿里云服务器使用教程:CentOS 7安装nginx详细步骤
目录 1、下载nginx压缩包 2、配置nginx安装所需环境 3、解压nginx压缩包 4、编译安装nginx 5、nginx启动...
Android JNI浅析、Java和Native通信对象的传值和回调
简单了解一下jni JNI是一个本地编程接口,它允许运行在Java虚拟机的Java代码与用其他语言(如C,C和汇编)编写的库交互。 jni函数签名 首先看一下java类型对应的jni类型: Java类型符号BooleanZByteBCharCShortSIntILongJFloatFDo…...
linux目录/usr/lib/systemd/system目录详解
文章目录前言一. systemd介绍二. service 脚本详解2.1 [Unit] 区块2.2 [Service] 区块2.3 [Install] 区块总结前言 init的进化经历了这么几个阶段: CentOS 5: SysV init,串行 CentOS 6:Upstart,并行,借鉴ubuntu CentOS 7:Syste…...
408考研计算机之计算机组成与设计——知识点及其做题经验篇目4:CPU的功能和基本结构
随着考研的慢慢复习,我们逐渐进入了计算机组成与设计的第五章中央处理器。它原名为CPU。姓C,名PU,字中央处理器,号计组难点,乃计算机之中心与核心部件,小编称之曰能算能控,赐名曰九天宏教普济生…...
2022-12-10青少年软件编程(C语言)等级考试试卷(五级)解析
2022-12-10青少年软件编程(C语言)等级考试试卷(五级)解析T1、漫漫回国路 2020年5月,国际航班机票难求。一位在美国华盛顿的中国留学生,因为一些原因必须在本周内回到北京。现在已知各个机场之间的航班情况,求问他回不回得来(不考虑转机次数和机票价格)。 时间限制:10…...
刷题专练之链表(一)
文章目录前言一、 移除链表元素1.题目介绍2.思路3.代码二、反转链表1.题目介绍2.思路3.代码三、链表的中间结点1.题目介绍2.思路3.代码四、链表的中间结点1.题目介绍2.思路3.代码前言 以下是链表经常考的面试题,我在这里进行归纳和讲解,采取的是循序渐进…...
elasticsearch高级查询api
yml配置 #es配置 spring:elasticsearch:rest:uris: 192.168.16.188:9200添加依赖 <dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId> </dependency>使用编程的形式…...
力扣-股票的资本损益
大家好,我是空空star,本篇带大家了解一道简单的力扣sql练习题。 文章目录前言一、题目:1393. 股票的资本损益二、解题1.正确示范①提交SQL运行结果2.正确示范②提交SQL运行结果3.正确示范③提交SQL运行结果4.正确示范④提交SQL运行结果5.其他…...
蓝桥杯刷题冲刺 | 倒计时26天
作者:指针不指南吗 专栏:蓝桥杯倒计时冲刺 🐾马上就要蓝桥杯了,最后的这几天尤为重要,不可懈怠哦🐾 文章目录1.路径2.特别数的和3.MP3储存4.求和1.路径 题目 链接: 路径 - 蓝桥云课 (lanqiao.cn…...
嵌入式软件开发之Linux 用户权限管理
目录 Ubuntu 用户系统 权限管理 权限管理命令 权限修改命令 chmod 文件归属者修改命令 chown Ubuntu 用户系统 Ubuntu 是一个多用户系统,我们可以给不同的使用者创建不同的用户账号,每个用户使用各自的账号登陆,使用用户账号的目的一是方便…...
2023-03-15 RabbitMQ
RabbitMQ整合 官网erlang版本 : 20.3.8.x 官方rabbitMq版本: rabbitmq-server-generic-unix-3.7.14.tar.xz 1.安装 1.1 安装erlang 1.安装环境 yum -y install make gcc gcc-c kernel-devel m4 ncurses-devel openssl-devel2.在/usr/local/下创建erlangapp文件…...
二叉树链式结构的实现
文章目录1.二叉树的遍历1.1前序、中序以及后序遍历1.2代码测试1.3层序遍历1.4二叉树遍历习题2.节点个数以及高度2.1二叉树节点个数2.2叶子节点个树2.3第k层节点个数2.4树的高度1.二叉树的遍历 1.1前序、中序以及后序遍历 学习二叉树结构,最简单的方式就是遍历。所…...
蓝桥杯刷题冲刺 | 倒计时28天
作者:指针不指南吗 专栏:蓝桥杯倒计时冲刺 🐾马上就要蓝桥杯了,最后的这几天尤为重要,不可懈怠哦🐾 文章目录1.卡片2.数字三角形3.购物单4.回文日期1.卡片 题目 链接: 卡片 - 蓝桥云课 (lanqiao…...
一文带你吃透操作系统
文章目录1. 进程、线程管理2. 内存管理3. 进程调度算法4. 磁盘调度算法5. 页面置换算法6. 网络系统7. 锁8. 操作系统知识点文章字数大约1.9万字,阅读大概需要65分钟,建议收藏后慢慢阅读!!!1. 进程、线程管理 进程和线程…...
手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
Docker 运行 Kafka 带 SASL 认证教程
Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明:server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...
STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
Nuxt.js 中的路由配置详解
Nuxt.js 通过其内置的路由系统简化了应用的路由配置,使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...
LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...
