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

【JavaScript】从事件流到事件委托

一、DOM事件基础

1. 什么是DOM事件?

DOM事件是用户或浏览器在网页上执行的某种动作,比如点击、鼠标移动、键盘输入等。JavaScript通过事件监听器来响应这些事件。

// 基本事件监听
document.querySelector('myButton').addEventListener('click', function() {console.log('按钮被点击了!');
});

2. 事件的三要素

  1. 事件源:触发事件的DOM元素
  2. 事件类型:click、mouseover等
  3. 事件处理函数:事件触发时执行的函数

二、事件流:捕获与冒泡

1. 事件流的三个阶段

事件流指的是事件完整执行过程中的流动路径
DOM事件流包括三个阶段:

  1. 捕获阶段:从window对象向下传播到目标元素(中国 陕西 西安)
  2. 目标阶段:在目标元素上触发
  3. 冒泡阶段:从目标元素向上传播回window对象(西安 陕西 中国),类比水烧开之前冒的泡泡

2. 代码演示

 .father {width: 500px;height: 50px;background-color: pink;}.son {width: 200px;height: 20px;background-color: blue;}
<div class="father"><div class="son"></div>
 const father = document.querySelector('.father')const son = document.querySelector('.son')// 在事件执行函数后面加上true变成事件捕获,点击蓝色方块以后弹窗的顺序是爷爷爸爸儿子document.addEventListener('click', function () {alert('我是爷爷')})father.addEventListener('click', function () {alert('我是爸爸')})son.addEventListener('click', function (e) {alert('我是儿子')})

3. 阻止事件冒泡

因为默认有冒泡模式的存在,所有容易导致事件影响父级元素。如果想要把事件限制在当前元素内就需要阻止冒泡,前提是事件冒泡之间需要拿到事件对象此方法可以阻断事件流动传播,不光在冒泡阶段有效,捕获阶段也有效

使用event.stopPropagation()方法可以阻止事件继续向上冒泡:

document.getElementById('child').addEventListener('click', function(e) {console.log('子元素点击,阻止冒泡');e.stopPropagation(); // 阻止事件继续向上冒泡
});

4. 阻止冒泡的适用场景

  1. 模态框点击:点击模态框内部时,阻止事件冒泡到背景层
  2. 嵌套菜单:子菜单展开时点击子菜单项,阻止触发父菜单的关闭逻辑
  3. 独立组件:组件内部事件不需要外部感知时

三、事件委托

事件委托是一种利用事件流的特征解决一些开发需求的技巧,可以减少注册次数,提高程序性能原理利用了事件冒泡的特点 :给父元素注册事件,当我们触发子元素的时候,会冒泡到父元素的身上,从而触发父元素的事件

3.1 为什么需要事件委托?

传统方式需要为每个元素添加事件监听器,性能低下:

利用事件冒泡机制,只需在父元素上添加一个事件监听器:

// 高效的事件委托
document.querySelector('myList').addEventListener('click', function(e) {if(e.target.tagName === 'LI') {console.log(e.target.textContent);}
});

注意: e.target是我们点击的对象 e.target.tagName是我们点击对象的标签名

3.4 事件委托与冒泡的关系

事件委托完全依赖于事件冒泡机制:

document.querySelector('parent').addEventListener('click', function(e) {const button = e.target.closest('button[data-action]');if(button) {handleAction(button.dataset.action);}
});
http://www.lryc.cn/news/590714.html

相关文章:

  • 再探多线程Ⅰ--- (创建思路+核心方法+代码样例)
  • [Mysql] Connector / C++ 使用
  • 二分查找算法(一)
  • 多目标优化|HKELM混合核极限学习机+NSGAII算法工艺参数优化、工程设计优化,四目标(最大化输出y1、最小化输出y2,y3,y4),Matlab完整源码
  • WP Force SSL Pro – HTTPS SSL Redirect Boost Your Website‘s Trust in Minutes!
  • 代码随想录算法训练营完结篇
  • 主流 TOP5 AI智能客服系统对比与推荐
  • Raydium CLMM 协议
  • Gradle vs Maven:构建工具世纪对决 —— 像乐高积木与标准模型之间的选择艺术
  • Transform的重要方法
  • excel分组展示业绩及增长率
  • 归一化与激活函数:深度学习的双引擎
  • 【WRFDA数据教程第一期】LITTLE_R 格式详细介绍
  • opencv 值类型 引用类型
  • 身份证号码姓名认证解决方案-身份证三要素API接口
  • Python+Selenium自动化
  • 【python】sys.executable、sys.argv、Path(__file__) 在PyInstaller打包前后的区别
  • Linux内核IPv4路由查找:LPC-Trie算法的深度实践
  • 门级网标仿真的时钟异常检查
  • 【C++高阶四】红黑树
  • ELK日志分析,涉及logstash、elasticsearch、kibana等多方面应用,必看!
  • 线程规则的制定者二:线程安全与冲入问题
  • 坚持继续布局32位MCU,进一步完善产品阵容,96Mhz主频CW32L012新品发布!
  • 选择亿林数据软件测试服务,为哈尔滨企业数字化转型赋能
  • 一叶障目不见森林
  • adb性能测试命令
  • 【知识图谱】Neo4j桌面版运行不起来怎么办?Neo4j Desktop无法打开!
  • Python18 —— 文件的写入
  • 大模型 认知能力 生物学启发
  • oracle会话控制和存储状态查询