〖大前端 - 基础入门三大核心之JS篇㊹〗- DOM事件委托
- 说明:该文属于 大前端全栈架构白宝书专栏,目前阶段免费,如需要项目实战或者是体系化资源,文末名片加V!
- 作者:不渴望力量的哈士奇(哈哥),十余年工作经验, 从事过全栈研发、产品经理等工作,目前在公司担任研发部门CTO。
- 荣誉:2022年度博客之星Top4、2023年度超级个体得主、谷歌与亚马逊开发者大会特约speaker、全栈领域优质创作者。
- 🏆 白宝书系列
- 🏅 启示录 - 攻城狮的自我修养
- 🏅 Python全栈白宝书
- 🏅 ChatGPT实践指南白宝书
- 🏅 产品思维训练白宝书
- 🏅 全域运营实战白宝书
- 🏅 大前端全栈架构白宝书
文章目录
- ⭐ DOM事件委托
⭐ DOM事件委托
事件委托可以帮助解决添加事件监听的两个问题:
- 批量添加事件监听大量占用内存会出现的性能问题
- 动态添加的元素必须添加事件监听,不能获得事件监听。
下面举两个案例来分别介绍着两个问题。
**案例一,批量添加事件监听会遇到性能问题:**页面上有一个无序列表,它内部共有20个<li>元素,请批量给它们添加点击事件监听,实现效果:点击哪个<li>元素,哪个<li>元素就变红。
题目分析:可以使用getElementsByTagName可以获取到li的数组,然后通过遍历的方式循环添加事件监听
<body><div><ul id="list"><li>项</li><li>项</li><li>项</li><li>项</li><li>项</li><li>项</li><li>项</li><li>项</li><li>项</li><li>项</li><li>项</li><li>项</li><li>项</li><li>项</li><li>项</li><li>项</li><li>项</li><li>项</li><li>项</li><li>项</li></ul></div><script>var oList = document.getElementById('list');var lis = oList.getElementsByTagName('li');for (var i = 0; i < lis.length; i++) {lis[i].onclick = function () {//在这个函数中,this表示点击的这个元素,this涉及函数上下文的相关知识,我们在“面向对象”中再介绍this.style.color = 'red';};};</script>
</body>

上面案例中,每一个事件监听注册都会消耗一定的系统内存,而批量添加事件会导致监听数量太多,内存消耗会非常大。并且每个事件处理函数都是不同的函数,这些函数本身也会占用内存。
**案例二,页面元素是动态添加的,每个元素都需要添加事件监听:**页面上有一个无序列表,它内部没有<li>元素,请制作一个按钮,点击这个按钮就能添加一个<li>元素。并且要求每个增加的<li>元素也要有事件监听,实现效果点击哪个<li>元素,哪个<li>元素就变红
题目分析:li的数量不是固定的,没办法使用循环遍历的方式去批量添加事件监听。我们给新创建的li节点添加事件监听
<body><button id="btn">点击我添加列表项</button><div><ul id="list"></ul></div><script>var oBtn = document.getElementById('btn');var oList = document.getElementById('list');oBtn.onclick = function () {//创建一个孤儿节点var oLi = document.createElement('li');oLi.innerHTML = '我是列表项';//上树oList.appendChild(oLi);//添加事件监听oLi.onclick = function () {oLi.style.color = 'red';};};</script>
</body>
上面案例中,同样会出现性能问题,因为每个事件处理函数都会占用新的内存,添加几个li,就会创建几个事件监听处理函数。
为了解决上面的问题,DOM提供了一种方法,即事件委托。
**事件委托:**利用事件冒泡机制,将
后代元素事件委托给祖先元素
比如下图中,点击任何一个<li>元素,事件都会通过事件冒泡传给祖先元素,我们只需要给<ul>添加事件监听就可以了,而不需要给每一个<li>都添加一遍事件监听。

事件委托需要结合
e.target属性来实现
| 属性 | 属性描述 |
|---|---|
| target | 触发此事件的最早元素,即“事件源元素” |
| currentTarget | 事件处理程序附加到的元素,与this非常相似 |
示例代码:
<body><ul id="list"><li>我是列表项</li><li>我是列表项</li><li>我是列表项</li><li>我是列表项</li><li>我是列表项</li></ul><script>var oList = document.getElementById('list');//给ul添加事件监听oList.onclick = function (e) {//e.target就表示点击的那个元素,即事件源元素,将事件源元素变红e.target.style.color = 'red';}</script>
</body>

可以自行尝试一下动态创建元素,点击按钮创建新的li,然后利用事件委托实现鼠标点击li时,文字变红。
事件委托的使用场景
-
当有大量元素需要批量添加事件监听时,使用
事件委托可以减少内存开销 -
当有动态元素节点上树时,使用事件委托可以让新上树的元素具有事件监听
事件委托的注意事项
-
注意事件是否冒泡,不能委托不冒泡的事件给祖先元素
在鼠标事件监听中,onmouseenter和onmouseover都表示“鼠标进入”,它们有什么区别呢?答:onmouseenter不冒泡,onmouseover冒泡;onmouseenter这个属性天生就是“不冒泡”的,相当于你事件处理函数附加给了哪个DOM节点,就是哪个DOM节点自己触发的事件,没有冒泡的过程。
示例代码:
//因为onmouseeter不冒泡,所以鼠标进入ul中的某个li时,整个ul都会变红,因为这个事件监听针对的是ul节点元素。 oList.onmouseenter = function (e) { e.target.style.color = 'red'; };解决办法:将onmouseenter换成onmouseover
-
最内层元素尽可能不能再有额外的内层元素了,否则可能实现不了理想的效果
比如下面的例子中,li内部还包了span标签,当鼠标点击span标签的内容时,只有span标签的变红了,而不能使整个li变红。
<body><ul id="list"><li><span>姓名:</span>我是列表项</li><li><span>电话:</span>我是列表项</li><li><span>地址:</span>我是列表项</li><li><span>邮箱:</span>我是列表项</li><li><span>手机:</span>我是列表项</li></ul><script>var oList = document.getElementById('list');//给ul添加事件监听oList.onclick = function (e) {e.target.style.color = 'red';};</script> </body>
相关文章:
〖大前端 - 基础入门三大核心之JS篇㊹〗- DOM事件委托
说明:该文属于 大前端全栈架构白宝书专栏,目前阶段免费,如需要项目实战或者是体系化资源,文末名片加V!作者:不渴望力量的哈士奇(哈哥),十余年工作经验, 从事过全栈研发、产品经理等工作…...
正是阶段高等数学复习--函数极限的计算
之前在预备阶段中函数极限的解决方式分三步,第一步观察形式并确定用什么方式来解决,第二步化简,化简方式一共有7种,分别是最重要的三种(等价替换、拆分极限存在的项、计算非零因子)以及次重要的4种…...
Linux-usb触摸板去除鼠标箭头
usb触摸板会同时加载hid-generic.c和hid-multitouch.c驱动 [ 213.602561] usb 4-1: new full-speed USB device number 2 using ohci-platform [ 213.834953] usb 4-1: New USB device found, idVendor6615, idProduct108c, bcdDevice 1.30 [ 213.835048] usb 4-1: New USB…...
【微信小程序】英文字母不换行问题 flex布局字符超出宽度折行问题:设置了word-break: break-all;和flex: 1;冲突flex不生效问题
flex布局中英文字符超出宽度不会自动折行的问题,但是设置了word-break: break-all;前面设置的flex: 1;就不生效了 1.英文字母不换行问题 .view_text {word-break: break-all; }如果使用flex仅仅设置word-break: break-all;是会影…...
python--自动化办公(Word)
python自动化办公之—Word python-docx库 1、安装python-docx库 pip install python-docx2、基本语法 1、打开文档 document Document() 2、加入标题 document.add_heading(总标题,0) document.add_heading(⼀级标题,1) document.add_heading(⼆级标题,2) 3、添加文本 para…...
sourceTree的下载和安装
sourceTree的下载和安装 一、概述 SourceTree 是一款免费的 Git 和 Hg 客户端管理工具,支持 Git 项目的创建、克隆、提交、push、pull 和合并等操作。它拥有一个精美简洁的界面,大大简化了开发者与代码库之间的 Git 操作方式,这对于不熟悉 …...
解决:ModuleNotFoundError: No module named ‘PyQt5‘
解决:ModuleNotFoundError: No module named ‘PyQt5’ 文章目录 解决:ModuleNotFoundError: No module named PyQt5背景报错问题报错翻译报错位置代码报错原因解决方法安装PyQt5在PyCharm中配置PyQt5对于新项目对于已有项目 今天的分享就到此结束了 背景…...
极客时间 - 如何成为学习高手【文章笔记 + 思考总结】
如何成为学习高手【文章笔记 思考总结】 高度自律 高度自律 5分钟起步法。 稍微走在计划前面。 替代拖延法。 自律:从不自律的念头中,约束自己。有变弱倾向时进行对抗。 在一种痛苦和另一种痛苦之间做选择,选择那个有意义的痛苦。 在某些固…...
前端笔记(二):CSS 选择器与特性
CSS(层叠样式表)是一种样式表语言,用于描述HTML或XML文档的呈现方式。它定义了如何在屏幕、纸张或其他媒体上显示文档的样式、布局和外观。 里面的代码由 选择器 { } 组成 体验 CSS CSS 可以让我们界面变得更加美观,这是 CSS 的…...
【每日一题】1423. 可获得的最大点数-2023.12.3
题目: 1423. 可获得的最大点数 几张卡牌 排成一行,每张卡牌都有一个对应的点数。点数由整数数组 cardPoints 给出。 每次行动,你可以从行的开头或者末尾拿一张卡牌,最终你必须正好拿 k 张卡牌。 你的点数就是你拿到手中的所有…...
VSCode修改C++版本
新下载了一下VSCode,想使用C17的特性std::optional,但是显示有错误,想想可能是C 版本的问题,查了一下资料,按下面的博客操作,果然解决了。 vscode设置c 版本...
31-WEB漏洞-文件操作之文件包含漏洞全解
31-WEB漏洞-文件操作之文件包含漏洞全解 一、本地包含1.1、无限制包含漏洞文件1.2、有限制包含漏洞文件1.2.1、绕过方法1.2.1.1、%00截断1.2.1.2、长度截断 二、远程包含2.1、无限制包含漏洞文件2.2、有限制包含漏洞文件 三、各种协议流提交流3.1、各协议的利用条件和方法3.1.1…...
预约系统源码解析:打造智能定制化预约服务的技术奇迹
在当今数字化时代,预约系统的重要性日益凸显,而预约系统源码的开放将为各行业带来更加灵活、智能的预约解决方案。本文将深入探讨预约系统源码的技术内幕,为开发者提供实用的代码示例,助力打造智能定制化的预约服务。 技术栈概览…...
关于Maxscript你了解多少?
MAXScript是Autodesk 3dMax的内置脚本语言。MAXScript为3dMax用户提供了以下功能: 编写程序使用的大部分方面的脚本,如建模、动画、材质、渲染等。 通过命令行侦听器窗口以交互方式控制程序。 在自定义实用工具面板卷展栏或无模式窗口中打包脚本&…...
Xshell全局去除提示音
使用Xshell的时候经常会按TAB或者一些操作指令的时候的时候听到提示音,非常的烦 通常来说在Xshell中可以单独修改每一个会话的属性,将提示音关闭,但是新增的会话依然带有提示音,还得一个个的关闭,非常麻烦,…...
JAVA代码优化:Spring中redis的工具类
基于Spring框架和Redis的缓存工具类。该类提供了一系列方法用于操作Redis缓存,包括设置缓存对象、设置缓存超时时间、获取缓存对象、删除对象、缓存List、Set、Map等操作。通过这些方法可以方便地对Redis进行数据缓存和读取操作。同时,该类使用了Spring的…...
MathType 7.5.2中文版软件使用期到了怎么办?
MathType 7.5.2中文版作为一款专业的公式编辑器,MathType受到很多人的青睐,它可以将编辑好的公式保存成多种图片格式或透明图片模式,可以很方便的添加或移除符号、表达式等模板(只需要简单地用鼠标拖进拖出即可),也可以…...
DOM 事件的注册和移除
前端面试大全DOM 事件的注册和移除 🌟经典真题 🌟DOM 注册事件 HTML 元素中注册事件 DOM0 级方式注册事件 DOM2 级方式注册事件 🌟DOM 移除事件 🌟真题解答 🌟总结 🌟经典真题 总结一下 DOM 中如何…...
挖漏洞之SQL注入
(一)漏洞原理 1、 漏洞原理 SQL注入的原理是,是应用系统没有对传递的参数进行过滤,让参数直接拼接到SQL语句中,攻击通过对参数进行篡改,当参数传递到数据库中,逻辑上就会发生变化,就…...
面试篇之微服务(二)
目录 服务容灾 21.什么是服务雪崩? 22.什么是服务熔断?什么是服务降级? 什么是服务熔断? 什么是服务降级? 有哪些熔断降级方案实现? 23.Hystrix怎么实现服务容错? 24.Sentinel怎么实现限…...
蓝芯算力:RISC-V 芯片破局之路
字节跳动前高管卢山创办的蓝芯算力完成数亿元融资,专注 RISC-V AI 算力芯片研发。目前已获超 20 万片订单,在 x86 和 ARM 主导的市场中开辟差异化道路。创始人背景与创业初衷蓝芯算力创始人卢山毕业于清华,有超 20 年芯片设计经验。他曾就职英…...
STM32F103RCT6小车调试实录:搞定TCRT5000循迹与TB6612FNG调速的5个常见坑
STM32F103RCT6小车调试实战:从TCRT5000循迹到TB6612FNG调速的深度排错指南 实验室里,当你看着自己组装的STM32智能小车在黑色轨迹线上歪歪扭扭地行驶,或是电机转速时快时慢不受控制时,那种挫败感我太熟悉了。这不是一篇教你如何从…...
OpenClaw跨平台脚本:Qwen3-32B生成的Python代码自动测试
OpenClaw跨平台脚本:Qwen3-32B生成的Python代码自动测试 1. 为什么需要AI全流程编程辅助 作为经常需要写脚本处理数据的开发者,我发现自己陷入了一个典型困境:每天要花大量时间编写重复性代码,而真正需要创造性思考的部分反而被…...
关于我使用MinMix创建了一个Tailwindcss学习网站
一、语言特性:Java 26 与模式匹配进化 1.1 Java 26 语言级别支持 IDEA 2026.1 EAP 最引人注目的变化之一,就是新增 Java 26 语言级别支持。这意味着开发者可以提前体验和测试即将在 JDK 26 中正式发布的语言特性。 其中最重要的变化是对 JEP 530 的全…...
Mac Mouse Fix:如何让第三方鼠标在macOS上释放全部潜能
Mac Mouse Fix:如何让第三方鼠标在macOS上释放全部潜能 【免费下载链接】mac-mouse-fix Mac Mouse Fix - A simple way to make your mouse better. 项目地址: https://gitcode.com/GitHub_Trending/ma/mac-mouse-fix Mac Mouse Fix是一款开源工具࿰…...
用PyTorch从零搭建U-Net:手把手教你搞定遥感图像分割(附完整代码)
用PyTorch从零搭建U-Net:手把手教你搞定遥感图像分割(附完整代码) 遥感图像分割是计算机视觉领域的重要应用方向,尤其在农业监测、城市规划、灾害评估等场景中发挥着关键作用。对于刚接触深度学习实践的开发者来说,从…...
如何通过AI技术提升图表创作效率?Next AI Draw.io全攻略
如何通过AI技术提升图表创作效率?Next AI Draw.io全攻略 【免费下载链接】next-ai-draw-io 项目地址: https://gitcode.com/GitHub_Trending/ne/next-ai-draw-io 技术人员日常工作中常会遇到这样的困境:花几小时绘制的架构图需要频繁修改&#x…...
突破性Unity游戏插件框架实战指南:BepInEx从零到精通的完全手册
突破性Unity游戏插件框架实战指南:BepInEx从零到精通的完全手册 【免费下载链接】BepInEx Unity / XNA game patcher and plugin framework 项目地址: https://gitcode.com/GitHub_Trending/be/BepInEx BepInEx是一款专为Unity游戏设计的革命性插件框架&…...
AMD ROCm:如何从零构建高性能GPU加速应用?
AMD ROCm:如何从零构建高性能GPU加速应用? 【免费下载链接】ROCm AMD ROCm™ Software - GitHub Home 项目地址: https://gitcode.com/GitHub_Trending/ro/ROCm AMD ROCm是一个完整的开源GPU计算平台,专为高性能计算和人工智能应用设计…...
CameraFileCopy:手机摄像头传输文件的终极解决方案,让数据传输不再受限!
CameraFileCopy:手机摄像头传输文件的终极解决方案,让数据传输不再受限! 【免费下载链接】cfc Demo/test android app for libcimbar. Copy files over the cell phone camera! 项目地址: https://gitcode.com/gh_mirrors/cfc/cfc 你是…...
