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

JS 事件流机制详解:冒泡、捕获与完整事件流

JS 事件流机制详解:冒泡、捕获与完整事件流

文章目录

  • JS 事件流机制详解:冒泡、捕获与完整事件流
    • 一、DOM 事件流基本概念
    • 二、事件捕获 (Event Capturing)
      • 特点
      • 代码示例
    • 三、事件冒泡 (Event Bubbling)
      • 特点
      • 代码示例
    • 四、完整事件流示例
      • HTML 结构
      • JavaScript 代码
    • 五、事件流控制方法
      • 1. 阻止事件传播
      • 2. 阻止默认行为
      • 3. 事件委托 (利用冒泡)
    • 六、实际应用场景
    • 七、注意事项

一、DOM 事件流基本概念

DOM 事件流描述了事件在网页中传播的完整过程,包含三个阶段:

  1. 捕获阶段 (Capture Phase):从 window 对象向下传播到目标元素

  2. 目标阶段 (Target Phase):事件到达目标元素

  3. 冒泡阶段 (Bubble Phase):从目标元素向上传播回 window 对象
    在这里插入图片描述

二、事件捕获 (Event Capturing)

特点

  • 传播方向:从最外层祖先元素向目标元素传播
  • 触发顺序:window → document → html → body → … → 目标元素
  • 应用场景:需要在事件到达目标前拦截处理

代码示例

// 添加捕获阶段事件监听 (第三个参数为true)
document.querySelector('#outer').addEventListener('click', function() {console.log('捕获阶段 - Outer');
}, true);document.querySelector('#inner').addEventListener('click', function() {console.log('捕获阶段 - Inner');
}, true);

三、事件冒泡 (Event Bubbling)

特点

  • 传播方向:从目标元素向最外层祖先元素传播
  • 触发顺序:目标元素 → … → body → html → document → window
  • 默认行为:大多数原生事件都会冒泡(focus/blur等除外)

代码示例

// 添加冒泡阶段事件监听 (第三个参数为false或省略)
document.querySelector('#outer').addEventListener('click', function() {console.log('冒泡阶段 - Outer');
});document.querySelector('#inner').addEventListener('click', function() {console.log('冒泡阶段 - Inner');
});

四、完整事件流示例

HTML 结构

<div id="grandparent">Grandparent<div id="parent">Parent<div id="child">Child</div></div>
</div>

JavaScript 代码

const elements = ['grandparent', 'parent', 'child'];// 为所有元素添加捕获和冒泡监听器
elements.forEach(id => {const el = document.getElementById(id);// 捕获阶段el.addEventListener('click', () => {console.log(`捕获阶段: ${id}`);}, true);// 冒泡阶段el.addEventListener('click', () => {console.log(`冒泡阶段: ${id}`);}, false);
});// 点击child元素后的输出顺序:
// 捕获阶段: grandparent
// 捕获阶段: parent
// 捕获阶段: child (实际是目标阶段)
// 冒泡阶段: child  (实际是目标阶段)
// 冒泡阶段: parent
// 冒泡阶段: grandparent

五、事件流控制方法

1. 阻止事件传播

element.addEventListener('click', function(event) {event.stopPropagation(); // 阻止继续传播// event.stopImmediatePropagation(); // 阻止所有后续监听器执行
});

2. 阻止默认行为

element.addEventListener('click', function(event) {event.preventDefault(); // 阻止默认行为(如链接跳转)
});

3. 事件委托 (利用冒泡)

// 只在父元素上设置监听器,处理子元素事件
document.querySelector('#parent').addEventListener('click', function(event) {if(event.target.id === 'child') {console.log('通过冒泡处理child点击');}
});

六、实际应用场景

  1. 事件委托:利用冒泡减少事件监听器数量

    // 动态列表项处理
    document.querySelector('#list').addEventListener('click', function(event) {if(event.target.classList.contains('item')) {console.log('点击了项目:', event.target.textContent);}
    });
    
  2. 拦截处理:使用捕获阶段提前处理事件

    // 全局点击拦截
    document.addEventListener('click', function(event) {if(event.target.tagName === 'A') {console.log('即将跳转到:', event.target.href);}
    }, true);
    
  3. 自定义组件:控制组件内外事件传播

    // 阻止组件内部事件冒泡到外部
    customComponent.addEventListener('click', function(event) {event.stopPropagation();// 组件内部处理逻辑
    });
    

七、注意事项

  1. 目标阶段特殊性
    • 在目标元素上,捕获和冒泡监听器按注册顺序执行
    • 不属于真正的捕获或冒泡阶段
  2. 不冒泡的事件
    • focus/blur
    • load/unload
    • mouseenter/mouseleave
  3. 性能考虑
    • 过多的事件监听器会影响性能
      目标阶段特殊性
    • 在目标元素上,捕获和冒泡监听器按注册顺序执行
    • 不属于真正的捕获或冒泡阶段
  4. 不冒泡的事件
    • focus/blur
    • load/unload
    • mouseenter/mouseleave
  5. 性能考虑
    • 过多的事件监听器会影响性能
    • 合理使用事件委托优化

相关文章:

JS 事件流机制详解:冒泡、捕获与完整事件流

JS 事件流机制详解&#xff1a;冒泡、捕获与完整事件流 文章目录 JS 事件流机制详解&#xff1a;冒泡、捕获与完整事件流一、DOM 事件流基本概念二、事件捕获 (Event Capturing)特点代码示例 三、事件冒泡 (Event Bubbling)特点代码示例 四、完整事件流示例HTML 结构JavaScript…...

MYSQL too many connection问题排查和修复

1.连接数据库 mysql -u root -p 1.1 查看mysql路径 如果没有配置mysql的环境变量&#xff0c;可以直接找mysql的安装目录 打开任务管理器-》服务-》Mysql(根据版本不同后面带有数字&#xff0c;找运行的那个) 打开服务->mysql->属性-》可执行文件的路径&#xff0c;…...

SpringCloudAlibaba和SpringBoot版本问题

SpringCloudAlibaba和SpringBoot版本问题 直接参考官方给出的版本说明&#xff0c;具体地址&#xff1a;https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E Spring Cloud Alibaba VersionSentinel VersionNacos VersionRocketMQ Ver…...

算法专题七:分治

快排 1.颜色分类 题目链接:75. 颜色分类 - 力扣(LeetCode) class Solution {public void swap(int[] nums, int i, int j){int t = nums[i];nums[i] = nums[j];nums[j] = t;}public void sortColors(int[] nums) {int left=-1 ,i=0 ,right=nums.length;while(i<right){i…...

Vue中虚拟DOM的原理与作用

绪论 首先我们先了解&#xff0c;DOM&#xff08;Document Object Model&#xff0c;文档对象模型&#xff09; 是浏览器对 HTML/XML 文档的结构化表示&#xff0c;它将文档解析为一个由节点&#xff08;Node&#xff09;和对象组成的树形结构&#xff08;称为 DOM 树&#xf…...

前端十种排序算法解析

1. 冒泡排序 1.1 说明 冒泡排序为一种常用排序算法&#xff0c;执行过程为从数组的第一个位置开始&#xff0c;相邻的进行比较&#xff0c;将最大的数移动到数组的最后位置执行的时间复杂度与空间复杂度为 o(n^2) 1.2 执行过程 从数组的第一个位置开始&#xff0c;截止位置为 …...

使用 C/C++ 和 OpenCV 添加图片水印

使用 C/C 和 OpenCV 添加图片水印 &#x1f5bc;️ 在数字图像处理中&#xff0c;添加水印是一种常见的操作&#xff0c;可以用于版权保护、品牌宣传或信息标注。本文将介绍如何使用 C/C 和强大的计算机视觉库 OpenCV 来实现将自定义水印&#xff08;图片或文字&#xff09;添…...

Secs/Gem第十二讲(基于secs4net项目的ChatGpt介绍)

好&#xff0c;那我们进入最关键的一讲—— 第十二讲&#xff1a;完整事件通知流程全景图——CEID 触发到主机接收的全过程 关键词&#xff1a;CEID 事件上报、S6F11 报文、事件触发流程、数据驱动机制、Report Dispatch、主机解析流程 本讲目标 你将彻底理解&#xff1a; 设…...

FastAPI实战起步:从Python环境到你的第一个“Hello World”API接口

上一篇文章中介绍了有关FastAPI的优势&#xff0c;本篇文章我将手把手带你从零开始&#xff0c;搭建FastAPI的开发环境&#xff0c;并成功运行你的第一个“Hello World”API。在开始之前&#xff0c;请确保你的电脑已经安装了Python 3.7或更高版本&#xff0c;以及VS Code&…...

使用vue3+ts+input封装上传组件,上传文件显示文件图标

效果图&#xff1a; 代码 <template><div class"custom-file-upload"><div class"upload"><!-- 显示已选择的文件 --><div class"file-list"><div v-for"(item, index) in state.filsList" :key&q…...

iOS 抖音导航栏首页一键分两列功能的实现

要实现 iOS 抖音首页导航栏的“一键分两列”功能&#xff08;通常指将单列内容切换为双列瀑布流布局&#xff09;&#xff0c;需结合自定义导航栏控件与布局动态切换逻辑。以下是关键实现步骤和技术要点&#xff0c;基于 iOS 原生开发框架&#xff08;Swift/Objective-C&#x…...

零基础入门 C 语言基础知识(含面试题):结构体、联合体、枚举、链表、环形队列、指针全解析!

&#x1f31f; 零基础入门 C 语言基础知识&#xff08;含面试题&#xff09;&#xff1a;结构体、联合体、枚举、链表、环形队列、指针全解析&#xff01; C 语言是所有程序员通向“系统世界”的第一把钥匙。很多嵌入式开发、操作系统内核、网络通信、图形引擎&#xff0c;背后…...

【Linux】Ubuntu 创建应用图标的方式汇总,deb/appimage/通用方法

Ubuntu 创建应用图标的方式汇总&#xff0c;deb/appimage/通用方法 对于标准的 Ubuntu&#xff08;使用 GNOME 桌面&#xff09;&#xff0c;desktop 后缀的桌面图标文件主要保存在以下三个路径&#xff1a; 当前用户的桌面目录&#xff08;这是最常见的位置&#xff09;。所…...

【Unity】R3 CSharp 响应式编程 - 使用篇(集合)(三)

1、ObservableList 基础 List 类型测试 using System;using System.Collections.Specialized;using ObservableCollections;using UnityEngine;namespace Aladdin.Standard.Observable.Collections.List{public class ObservableListTest : MonoBehaviour{protected readonly O…...

振动力学:弹性杆的纵向振动(固有振动和固有频率的概念)

文章1、2、3中讨论的是离散系统的振动特性,然而实际系统的惯性质量、弹性、阻尼等特性都是连续分布的,因而成为连续系统或分布参数系统。确定连续介质中无数个点的运动需要无限个广义坐标,因此也称为无限自由度系统,典型的结构例如:弦、杆、膜、环、梁、板、壳等,也称为弹…...

LangGraph--Agent工作流

Agent的工作流 下面展示了如何创建一个“计划并执行”风格的代理。 这在很大程度上借鉴了 计划和解决 论文以及Baby-AGI项目。 核心思想是先制定一个多步骤计划&#xff0c;然后逐项执行。完成一项特定任务后&#xff0c;您可以重新审视计划并根据需要进行修改。 般的计算图如…...

Spring Boot 常用注解面试题深度解析

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot 常用注解面试题深度解析一、核心…...

Linux系统的CentOS7发行版安装MySQL80

文章目录 前言Linux命令行内的”应用商店”安装CentOS的安装软件的yum命令安装MySQL1. 配置yum仓库2. 使用yum安装MySQL3. 安装完成后&#xff0c;启动MySQL并配置开机自启动4. 检查MySQL的运行状态 MySQL的配置1. 获取MySQL的初始密码2. 登录MySQL数据库系统3. 修改root密码4.…...

408第一季 - 数据结构 - 栈与队列

栈 闲聊 栈是一个线性表 栈的特点是后进先出 然后是一个公式 比如123要入栈&#xff0c;一共有5种排列组合的出栈 栈的数组实现 这里有两种情况&#xff0c;&#xff0c;一个是有下标为-1的&#xff0c;一个没有 代码不用看&#xff0c;真题不会考 栈的链式存储结构 L ->…...

【RTP】Intra-Refresh模式下的 H.264 输出,RTP打包的方式和普通 H.264 流并没有本质区别

对于 Intra-Refresh 模式下的 H.264 输出,RTP 打包 的方式和普通 H.264 流并没有本质区别:你依然是在对一帧一帧的 NAL 单元进行 RTP 分包,只不过这些 NAL 单元内部有部分宏块是 “帧内编码” 而已。下面分步骤说明: 1. 原理回顾:RFC 6184 H.264 over RTP 按照 RFC 6184 …...

nano编辑器的详细使用教程

以下是 Linux 下 nano 编辑器 的详细使用指南&#xff0c;涵盖安装、基础操作、高级功能、快捷键以及常见问题处理。 一、安装 nano 大多数 Linux 发行版已预装 nano。如果没有安装&#xff0c;可以通过以下命令安装&#xff1a; Debian/Ubuntu 系&#xff1a;sudo apt update…...

Redis实战-消息队列篇

前言&#xff1a; 讲讲做消息队列遇到的问题。 今日所学&#xff1a; 异步优化消息队列基于stream实现异步下单 1. 异步优化 1.1 需求分析 1.1.1 现有下单流程&#xff1a; 1.查询优惠劵 2.判断是否是秒杀时间&#xff0c;库存是否充足 3.实现一人一单 在这个功能中&…...

(三)Linux性能优化-CPU-CPU 使用率

CPU使用率 user&#xff08;通常缩写为 us&#xff09;&#xff0c;代表用户态 CPU 时间。注意&#xff0c;它不包括下面的 nice 时间&#xff0c;但包括了 guest 时间。nice&#xff08;通常缩写为 ni&#xff09;&#xff0c;代表低优先级用户态 CPU 时间&#xff0c;也就是进…...

佰力博科技与您探讨材料介电性能测试的影响因素

1、频率依赖性 材料的介电性能通常具有显著的频率依赖性。在低频下&#xff0c;偶极子的取向极化占主导&#xff0c;介电常数较高&#xff1b;而在高频下&#xff0c;偶极子的取向极化滞后&#xff0c;导致介电常数下降&#xff0c;同时介电损耗增加。例如&#xff0c;VHB4910…...

K8S认证|CKS题库+答案| 4. RBAC - RoleBinding

目录 4. RBAC - RoleBinding 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、查看SA和role 3&#xff09;、编辑 role-1 权限 4&#xff09;、检查role 5&#xff09;、创建 role和 rolebinding 6&#xff0…...

React 新项目

使用git bash 创建一个新项目 建议一开始就创建TS项目 原因在Webpack中改配置麻烦 编译方法:ts compiler 另一种 bable 最好都配置 $ create-react-app cloundmusic --template typescript 早期react项目 yarn 居多 目前npm包管理居多 目前pnpm不通用 icon 在public文件夹中…...

解决MySQL8.4报错ERROR 1524 (HY000): Plugin ‘mysql_native_password‘ is not loaded

最近使用了MySQL8.4 , 服务启动成功,但是就是无法登陆,并且报错: ERROR 1524 (HY000): Plugin mysql_native_password is not loaded 使用如下的命令也报错 mysql -u root -p -P 3306 问题分析: 在MySQL 8.0版本中,默认的认证插件从mysql_native_password变更为cachi…...

AI编程在BOSS项目的实践经验分享

前言 在人工智能技术革新浪潮的推动下&#xff0c;智能编程助手正以前所未有的速度重塑开发领域。这些基于AI的代码辅助工具通过智能提示生成、实时错误检测和自动化重构等功能&#xff0c;显著提升了软件工程的全流程效率。无论是初入行业的开发者还是资深程序员&#xff0c;…...

力扣-131.分割回文串

题目描述 给你一个字符串 s&#xff0c;请你将 s 分割成一些 子串&#xff0c;使每个子串都是 回文串 。返回 s 所有可能的分割方案。 class Solution {List<List<String>> res new ArrayList<>();List<String> path new ArrayList<>();void…...

数学:”度量空间”了解一下?

度量空间是现代数学中一种基本且重要的抽象空间。以下是对它的详细介绍&#xff1a; 定义 相关概念 常见的度量空间举例 度量空间的类型 度量空间的作用 度量空间是拓扑空间的一种特殊情况&#xff0c;它为拓扑空间的研究提供了具体的模型和实例。同时&#xff0c;度量空间在…...