当前位置: 首页 > news >正文

深入理解JavaScript的事件冒泡与事件捕获

前言

JavaScript中提供了很多操作DOM的API。

事件冒泡事件捕获是指浏览器中处理DOM元素上事件的两种不同方式。事件冒泡和事件捕获都是JavaScript事件模型中的一部分,可以用来处理事件

对于这个问题,在实际开发中,并不是非常重要,因为在工作中我们基本上不会直接操作DOM,为了高效一般都是通过Vue、React这些框架,所以关于事件处理程序的一些坑直接就被避免了!!!

但是,多了解一点是没有坏处的,毕竟面试会考~

一、事件冒泡

事件冒泡(Event Bubbling)是指当一个元素触发了某个事件时,该事件会从最具体的元素开始逐级向上传播到较为不具体的元素(也就是从子元素向父元素方向传播),直到传播到文档的根节点为止。这种传播方式就像气泡从水底冒出水面一样,所以叫做事件冒泡。

举个例子,假设有一个包含两个嵌套 div 元素的 HTML 结构如下:

<div id="outer"><div id="inner"><button>点击我</button></div>
</div>

当我们在按钮上点击时,事件会按照如下顺序进行冒泡

  1. 首先,按钮元素触发点击事件。

  1. 然后,该事件会从最具体的元素(按钮元素)开始向外传播到其父元素(内部 div 元素)。

  1. 接着,该事件继续向外传播到外部 div 元素。

  1. 最后,该事件传播到文档的根节点(HTML 元素)。

在这个过程中,每个元素都可以在自己的事件处理程序中处理该事件。这意味着,当点击按钮时,除了按钮本身的事件处理程序之外,内部 div 和外部 div 元素也可以捕获并处理该事件

可以通过 JavaScript 的 Event 对象来阻止事件冒泡。例如,可以使用 event.stopPropagation() 方法来阻止事件继续向外传播。

二、事件捕获

事件捕获(Event Capturing)是一种处理事件的方式,与事件冒泡相反。事件捕获从文档根节点开始,逐级向下传播到最具体的元素,也就是从父元素向子元素方向传播。

与事件冒泡不同,事件捕获在元素本身触发事件之前被触发。具体来说,事件会从文档根节点开始向下传播,直到达到触发该事件的最具体的元素。这个过程中,每个元素都可以在自己的事件处理程序中处理该事件。

还是刚才的例子

<div id="outer"><div id="inner"><button>点击我</button></div>
</div>

当我们在按钮上点击时,事件会按照如下顺序进行捕获:

  1. 首先,该事件从文档的根节点开始向下传播到最外层的元素(外部 div 元素)。

  1. 然后,该事件继续向下传播到内部的 div 元素。

  1. 最后,该事件传播到触发该事件的最具体的元素(按钮元素)。

在这个过程中,每个元素都可以在自己的事件处理程序中处理该事件。这意味着,当点击按钮时,除了按钮本身的事件处理程序之外,内部 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事件模型的优点:

  1. 支持事件捕获和事件冒泡。事件捕获和事件冒泡是DOM2事件模型的核心特性之一,使得事件处理程序能够在DOM树中不同的层级进行注册,从而更好地控制事件的传播和处理。

  1. 可以同时添加多个事件处理程序。通过addEventListener()方法,可以为同一个事件添加多个事件处理程序,而不会覆盖先前添加的事件处理程序。

  1. 可以从HTML元素上删除事件处理程序。使用removeEventListener()方法可以方便地从HTML元素上删除事件处理程序,而不必像DOM0事件模型那样通过将事件处理程序设置为null来达到删除的效果。

  1. 支持事件对象。在DOM2事件模型中,事件处理程序会接收一个事件对象作为参数,该事件对象包含有关事件的详细信息,例如事件类型、事件目标、鼠标位置等,从而能够更好地处理和控制事件。

综上所述,DOM2事件模型是一种功能更强大、更灵活的事件模型,相比于DOM0事件模型和IE事件模型更加推荐使用。

四、两者能干什么?

使用事件冒泡和事件捕获可以实现:

  1. 事件委托:可以将事件处理程序绑定到父元素而不是子元素上。当子元素触发该事件时,事件将沿着冒泡路径传递到父元素,由父元素的事件处理程序进行处理。这样可以减少事件处理程序的数量,提高性能和可维护性。

  1. 事件拦截:通过在事件处理程序中调用 event.stopPropagation() 方法,可以阻止事件继续传播,从而避免不必要的事件触发和处理。

  1. 多个事件处理程序的执行顺序控制:通过在捕获或冒泡阶段注册事件处理程序,并控制其在事件传播路径上的位置,可以控制多个事件处理程序的执行顺序。

总之,了解和使用事件冒泡和事件捕获可以帮助我们更好地处理 HTML 和 JavaScript 中的事件,提高代码的可维护性和性能。

相关文章:

深入理解JavaScript的事件冒泡与事件捕获

前言JavaScript中提供了很多操作DOM的API。事件冒泡和事件捕获是指浏览器中处理DOM元素上事件的两种不同方式。事件冒泡和事件捕获都是JavaScript事件模型中的一部分&#xff0c;可以用来处理事件。对于这个问题&#xff0c;在实际开发中&#xff0c;并不是非常重要&#xff0c…...

格密码学习笔记(六):格中模运算

文章目录格中取模运算CVP和格的陪集致谢格中取模运算 定义&#xff08;格的基本区域&#xff09; 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++】非常重要的——多态

凡是面向对象的语言&#xff0c;都有三大特性&#xff0c;继承&#xff0c;封装和多态&#xff0c;但并不是只有这三个特性&#xff0c;是因为者三个特性是最重要的特性&#xff0c;那今天我们一起来看多态&#xff01; 目录 1.多态的概念 1.1虚函数 1.2虚函数的重写 1.3虚…...

发票账单很多?python助你批量完成数据提取

每天面对成堆的发票&#xff0c;无论是税务发票还是承兑单据&#xff0c;抑或是其他各类公司数据要从照片、PDF等不同格式的内容中提取&#xff0c;我们都有必要进行快速办公的能力提升。因此&#xff0c;我们的目标要求就十分明显了&#xff0c;首先要从图片中获取数据&#x…...

[闪存2.1] NAND FLASH特性串烧 | 不了解闪存特性,你能用好闪存产品吗?

前言 为了利用好闪存, 发挥闪存的优势, 以达到更好的性能和使用寿命, 那自然要求了解闪存特性。 闪存作为一种相对较新的存储介质, 有很多特别的特性。 一.闪存的特性 凡是采用Flash Memory的存储设备,可以统称为闪存存储。我们经常谈的固态硬盘(SSD),可以由volatile/…...

面试官问我按钮级别权限怎么控制,我说v-if,面试官说再见

最近的面试中有一个面试官问我按钮级别的权限怎么控制&#xff0c;我说直接v-if啊&#xff0c;他说不够好&#xff0c;我说我们项目中按钮级别的权限控制情况不多&#xff0c;所以v-if就够了&#xff0c;他说不够通用&#xff0c;最后他对我的评价是做过很多东西&#xff0c;但…...

阿里云服务器使用教程:CentOS 7安装nginx详细步骤

目录 1、下载nginx压缩包 2、配置nginx安装所需环境 3、解压nginx压缩包 4、编译安装nginx 5、nginx启动...

Android JNI浅析、Java和Native通信对象的传值和回调

简单了解一下jni JNI是一个本地编程接口&#xff0c;它允许运行在Java虚拟机的Java代码与用其他语言&#xff08;如C,C和汇编&#xff09;编写的库交互。 jni函数签名 首先看一下java类型对应的jni类型&#xff1a; Java类型符号BooleanZByteBCharCShortSIntILongJFloatFDo…...

linux目录/usr/lib/systemd/system目录详解

文章目录前言一. systemd介绍二. service 脚本详解2.1 [Unit] 区块2.2 [Service] 区块2.3 [Install] 区块总结前言 init的进化经历了这么几个阶段&#xff1a; CentOS 5: SysV init,串行 CentOS 6&#xff1a;Upstart,并行&#xff0c;借鉴ubuntu CentOS 7&#xff1a;Syste…...

408考研计算机之计算机组成与设计——知识点及其做题经验篇目4:CPU的功能和基本结构

随着考研的慢慢复习&#xff0c;我们逐渐进入了计算机组成与设计的第五章中央处理器。它原名为CPU。姓C&#xff0c;名PU&#xff0c;字中央处理器&#xff0c;号计组难点&#xff0c;乃计算机之中心与核心部件&#xff0c;小编称之曰能算能控&#xff0c;赐名曰九天宏教普济生…...

2022-12-10青少年软件编程(C语言)等级考试试卷(五级)解析

2022-12-10青少年软件编程(C语言)等级考试试卷(五级)解析T1、漫漫回国路 2020年5月,国际航班机票难求。一位在美国华盛顿的中国留学生,因为一些原因必须在本周内回到北京。现在已知各个机场之间的航班情况,求问他回不回得来(不考虑转机次数和机票价格)。 时间限制:10…...

刷题专练之链表(一)

文章目录前言一、 移除链表元素1.题目介绍2.思路3.代码二、反转链表1.题目介绍2.思路3.代码三、链表的中间结点1.题目介绍2.思路3.代码四、链表的中间结点1.题目介绍2.思路3.代码前言 以下是链表经常考的面试题&#xff0c;我在这里进行归纳和讲解&#xff0c;采取的是循序渐进…...

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>使用编程的形式…...

力扣-股票的资本损益

大家好&#xff0c;我是空空star&#xff0c;本篇带大家了解一道简单的力扣sql练习题。 文章目录前言一、题目&#xff1a;1393. 股票的资本损益二、解题1.正确示范①提交SQL运行结果2.正确示范②提交SQL运行结果3.正确示范③提交SQL运行结果4.正确示范④提交SQL运行结果5.其他…...

蓝桥杯刷题冲刺 | 倒计时26天

作者&#xff1a;指针不指南吗 专栏&#xff1a;蓝桥杯倒计时冲刺 &#x1f43e;马上就要蓝桥杯了&#xff0c;最后的这几天尤为重要&#xff0c;不可懈怠哦&#x1f43e; 文章目录1.路径2.特别数的和3.MP3储存4.求和1.路径 题目 链接&#xff1a; 路径 - 蓝桥云课 (lanqiao.cn…...

嵌入式软件开发之Linux 用户权限管理

目录 Ubuntu 用户系统 权限管理 权限管理命令 权限修改命令 chmod 文件归属者修改命令 chown Ubuntu 用户系统 Ubuntu 是一个多用户系统&#xff0c;我们可以给不同的使用者创建不同的用户账号&#xff0c;每个用户使用各自的账号登陆&#xff0c;使用用户账号的目的一是方便…...

2023-03-15 RabbitMQ

RabbitMQ整合 官网erlang版本 : 20.3.8.x 官方rabbitMq版本&#xff1a; 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前序、中序以及后序遍历 学习二叉树结构&#xff0c;最简单的方式就是遍历。所…...

蓝桥杯刷题冲刺 | 倒计时28天

作者&#xff1a;指针不指南吗 专栏&#xff1a;蓝桥杯倒计时冲刺 &#x1f43e;马上就要蓝桥杯了&#xff0c;最后的这几天尤为重要&#xff0c;不可懈怠哦&#x1f43e; 文章目录1.卡片2.数字三角形3.购物单4.回文日期1.卡片 题目 链接&#xff1a; 卡片 - 蓝桥云课 (lanqiao…...

一文带你吃透操作系统

文章目录1. 进程、线程管理2. 内存管理3. 进程调度算法4. 磁盘调度算法5. 页面置换算法6. 网络系统7. 锁8. 操作系统知识点文章字数大约1.9万字&#xff0c;阅读大概需要65分钟&#xff0c;建议收藏后慢慢阅读&#xff01;&#xff01;&#xff01;1. 进程、线程管理 进程和线程…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする

日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

Ubuntu系统多网卡多相机IP设置方法

目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机&#xff0c;交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息&#xff0c;系统版本&#xff1a;Ubuntu22.04.5 LTS&#xff1b;内核版本…...

高防服务器价格高原因分析

高防服务器的价格较高&#xff0c;主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因&#xff1a; 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器&#xff0c;因此…...

React核心概念:State是什么?如何用useState管理组件自己的数据?

系列回顾&#xff1a; 在上一篇《React入门第一步》中&#xff0c;我们已经成功创建并运行了第一个React项目。我们学会了用Vite初始化项目&#xff0c;并修改了App.jsx组件&#xff0c;让页面显示出我们想要的文字。但是&#xff0c;那个页面是“死”的&#xff0c;它只是静态…...

写一个shell脚本,把局域网内,把能ping通的IP和不能ping通的IP分类,并保存到两个文本文件里

写一个shell脚本&#xff0c;把局域网内&#xff0c;把能ping通的IP和不能ping通的IP分类&#xff0c;并保存到两个文本文件里 脚本1 #!/bin/bash #定义变量 ip10.1.1 #循环去ping主机的IP for ((i1;i<10;i)) doping -c1 $ip.$i &>/dev/null[ $? -eq 0 ] &&am…...

Qwen系列之Qwen3解读:最强开源模型的细节拆解

文章目录 1.1分钟快览2.模型架构2.1.Dense模型2.2.MoE模型 3.预训练阶段3.1.数据3.2.训练3.3.评估 4.后训练阶段S1: 长链思维冷启动S2: 推理强化学习S3: 思考模式融合S4: 通用强化学习 5.全家桶中的小模型训练评估评估数据集评估细节评估效果弱智评估和民间Arena 分析展望 如果…...