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

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. 性能考虑
    • 过多的事件监听器会影响性能
    • 合理使用事件委托优化
http://www.xdnf.cn/news/13107.html

相关文章:

  • VibePlayer
  • wsl开启即闪退
  • surfer15安装
  • DeepSeek 赋能数字文创:开启内容生成 “智” 变新时代
  • C++_核心编程_多继承语法
  • 【项目实践】SMBMS(Javaweb版)(四)用户管理
  • 2.2.1 ASPICE的需求收集
  • 1 Studying《蓝牙核心规范5.3》
  • 交流电机深度解析:从基础到实战的全面指南
  • 删除有序数组中的重复项
  • 【周输入】250531阅读推荐-2
  • Learning Smooth Humanoid Locomotion through Lipschitz-Constrained Policies
  • 麦克风前的“定心术”:用正念与演讲焦虑温柔和解
  • JS Day05
  • ESP32 在Arduino开发环境中,如果程序运行报错如何定位程序报错是哪行代码
  • 香橙派3B学习笔记7:snap安装管理软件包_打包程序与依赖
  • day 48
  • 注意高温陷阱?---可恢复保险丝应用失效案例分享
  • 自动交换两个文件的文件名 VSB脚本技巧 电脑技巧
  • 操作系统期末版
  • 免杀对抗--PE文件结构
  • 汽车车载软件平台化项目规模颗粒度选择的一些探讨
  • 【学习笔记】TLS
  • 贝叶斯医学分析中“先验”的如何进行选择(文献解读)
  • Java【基础篇0】
  • java中装饰模式
  • Go内存池设计与实现:减少GC压力
  • ASM,LVM,扫描并扩容步骤-linux
  • 什么是双脉冲测试?
  • 【C++】第十一节—一文详解vector(使用+杨辉三角+深度剖析+模拟实现+细节详细补充)