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

〖大前端 - 基础入门三大核心之JS篇㊹〗- DOM事件委托

  • 说明:该文属于 大前端全栈架构白宝书专栏,目前阶段免费如需要项目实战或者是体系化资源,文末名片加V!
  • 作者:不渴望力量的哈士奇(哈哥),十余年工作经验, 从事过全栈研发、产品经理等工作,目前在公司担任研发部门CTO。
  • 荣誉:2022年度博客之星Top4、2023年度超级个体得主、谷歌与亚马逊开发者大会特约speaker全栈领域优质创作者

  • 🏆 白宝书系列
    • 🏅 启示录 - 攻城狮的自我修养
    • 🏅 Python全栈白宝书
    • 🏅 ChatGPT实践指南白宝书
    • 🏅 产品思维训练白宝书
    • 🏅 全域运营实战白宝书
    • 🏅 大前端全栈架构白宝书


文章目录

  • ⭐ DOM事件委托

⭐ DOM事件委托

事件委托可以帮助解决添加事件监听的两个问题:

  1. 批量添加事件监听大量占用内存会出现的性能问题
  2. 动态添加的元素必须添加事件监听,不能获得事件监听。

下面举两个案例来分别介绍着两个问题。

**案例一,批量添加事件监听会遇到性能问题:**页面上有一个无序列表,它内部共有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>

image-20230423174447970

上面案例中,每一个事件监听注册都会消耗一定的系统内存,而批量添加事件会导致监听数量太多,内存消耗会非常大。并且每个事件处理函数都是不同的函数,这些函数本身也会占用内存。

**案例二,页面元素是动态添加的,每个元素都需要添加事件监听:**页面上有一个无序列表,它内部没有<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>都添加一遍事件监听。

image-20230424101047900

事件委托需要结合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>

image-20230424102428644

可以自行尝试一下动态创建元素,点击按钮创建新的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>
    

    image-20230424104833829

相关文章:

〖大前端 - 基础入门三大核心之JS篇㊹〗- DOM事件委托

说明&#xff1a;该文属于 大前端全栈架构白宝书专栏&#xff0c;目前阶段免费&#xff0c;如需要项目实战或者是体系化资源&#xff0c;文末名片加V&#xff01;作者&#xff1a;不渴望力量的哈士奇(哈哥)&#xff0c;十余年工作经验, 从事过全栈研发、产品经理等工作&#xf…...

正是阶段高等数学复习--函数极限的计算

之前在预备阶段中函数极限的解决方式分三步&#xff0c;第一步观察形式并确定用什么方式来解决&#xff0c;第二步化简&#xff0c;化简方式一共有7种&#xff0c;分别是最重要的三种&#xff08;等价替换、拆分极限存在的项、计算非零因子&#xff09;以及次重要的4种&#xf…...

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布局中英文字符超出宽度不会自动折行的问题&#xff0c;但是设置了word-break: break-all&#xff1b;前面设置的flex: 1&#xff1b;就不生效了 1.英文字母不换行问题 .view_text {word-break: break-all; }如果使用flex仅仅设置word-break: break-all&#xff1b;是会影…...

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 客户端管理工具&#xff0c;支持 Git 项目的创建、克隆、提交、push、pull 和合并等操作。它拥有一个精美简洁的界面&#xff0c;大大简化了开发者与代码库之间的 Git 操作方式&#xff0c;这对于不熟悉 …...

解决:ModuleNotFoundError: No module named ‘PyQt5‘

解决&#xff1a;ModuleNotFoundError: No module named ‘PyQt5’ 文章目录 解决&#xff1a;ModuleNotFoundError: No module named PyQt5背景报错问题报错翻译报错位置代码报错原因解决方法安装PyQt5在PyCharm中配置PyQt5对于新项目对于已有项目 今天的分享就到此结束了 背景…...

极客时间 - 如何成为学习高手【文章笔记 + 思考总结】

如何成为学习高手【文章笔记 思考总结】 高度自律 高度自律 5分钟起步法。 稍微走在计划前面。 替代拖延法。 自律&#xff1a;从不自律的念头中&#xff0c;约束自己。有变弱倾向时进行对抗。 在一种痛苦和另一种痛苦之间做选择&#xff0c;选择那个有意义的痛苦。 在某些固…...

前端笔记(二):CSS 选择器与特性

CSS&#xff08;层叠样式表&#xff09;是一种样式表语言&#xff0c;用于描述HTML或XML文档的呈现方式。它定义了如何在屏幕、纸张或其他媒体上显示文档的样式、布局和外观。 里面的代码由 选择器 { } 组成 体验 CSS CSS 可以让我们界面变得更加美观&#xff0c;这是 CSS 的…...

【每日一题】1423. 可获得的最大点数-2023.12.3

题目&#xff1a; 1423. 可获得的最大点数 几张卡牌 排成一行&#xff0c;每张卡牌都有一个对应的点数。点数由整数数组 cardPoints 给出。 每次行动&#xff0c;你可以从行的开头或者末尾拿一张卡牌&#xff0c;最终你必须正好拿 k 张卡牌。 你的点数就是你拿到手中的所有…...

VSCode修改C++版本

新下载了一下VSCode&#xff0c;想使用C17的特性std::optional&#xff0c;但是显示有错误&#xff0c;想想可能是C 版本的问题&#xff0c;查了一下资料&#xff0c;按下面的博客操作&#xff0c;果然解决了。 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…...

预约系统源码解析:打造智能定制化预约服务的技术奇迹

在当今数字化时代&#xff0c;预约系统的重要性日益凸显&#xff0c;而预约系统源码的开放将为各行业带来更加灵活、智能的预约解决方案。本文将深入探讨预约系统源码的技术内幕&#xff0c;为开发者提供实用的代码示例&#xff0c;助力打造智能定制化的预约服务。 技术栈概览…...

关于Maxscript你了解多少?

MAXScript是Autodesk 3dMax的内置脚本语言。MAXScript为3dMax用户提供了以下功能&#xff1a; 编写程序使用的大部分方面的脚本&#xff0c;如建模、动画、材质、渲染等。 通过命令行侦听器窗口以交互方式控制程序。 在自定义实用工具面板卷展栏或无模式窗口中打包脚本&…...

Xshell全局去除提示音

使用Xshell的时候经常会按TAB或者一些操作指令的时候的时候听到提示音&#xff0c;非常的烦 通常来说在Xshell中可以单独修改每一个会话的属性&#xff0c;将提示音关闭&#xff0c;但是新增的会话依然带有提示音&#xff0c;还得一个个的关闭&#xff0c;非常麻烦&#xff0c;…...

JAVA代码优化:Spring中redis的工具类

基于Spring框架和Redis的缓存工具类。该类提供了一系列方法用于操作Redis缓存&#xff0c;包括设置缓存对象、设置缓存超时时间、获取缓存对象、删除对象、缓存List、Set、Map等操作。通过这些方法可以方便地对Redis进行数据缓存和读取操作。同时&#xff0c;该类使用了Spring的…...

MathType 7.5.2中文版软件使用期到了怎么办?

MathType 7.5.2中文版作为一款专业的公式编辑器&#xff0c;MathType受到很多人的青睐&#xff0c;它可以将编辑好的公式保存成多种图片格式或透明图片模式&#xff0c;可以很方便的添加或移除符号、表达式等模板&#xff08;只需要简单地用鼠标拖进拖出即可)&#xff0c;也可以…...

DOM 事件的注册和移除

前端面试大全DOM 事件的注册和移除 &#x1f31f;经典真题 &#x1f31f;DOM 注册事件 HTML 元素中注册事件 DOM0 级方式注册事件 DOM2 级方式注册事件 &#x1f31f;DOM 移除事件 &#x1f31f;真题解答 &#x1f31f;总结 &#x1f31f;经典真题 总结一下 DOM 中如何…...

挖漏洞之SQL注入

&#xff08;一&#xff09;漏洞原理 1、 漏洞原理 SQL注入的原理是&#xff0c;是应用系统没有对传递的参数进行过滤&#xff0c;让参数直接拼接到SQL语句中&#xff0c;攻击通过对参数进行篡改&#xff0c;当参数传递到数据库中&#xff0c;逻辑上就会发生变化&#xff0c;就…...

面试篇之微服务(二)

目录 服务容灾 21.什么是服务雪崩&#xff1f; 22.什么是服务熔断&#xff1f;什么是服务降级&#xff1f; 什么是服务熔断&#xff1f; 什么是服务降级&#xff1f; 有哪些熔断降级方案实现&#xff1f; 23.Hystrix怎么实现服务容错&#xff1f; 24.Sentinel怎么实现限…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂&#xff08;如抗体、抑制肽&#xff09;在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上&#xff0c;高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术&#xff0c;但这类方法普遍面临资源消耗巨大、研发周期冗长…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

Python如何给视频添加音频和字幕

在Python中&#xff0c;给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加&#xff0c;包括必要的代码示例和详细解释。 环境准备 在开始之前&#xff0c;需要安装以下Python库&#xff1a;…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

20个超级好用的 CSS 动画库

分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码&#xff0c;而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库&#xff0c;可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画&#xff0c;可以包含在你的网页或应用项目中。 3.An…...

三分算法与DeepSeek辅助证明是单峰函数

前置 单峰函数有唯一的最大值&#xff0c;最大值左侧的数值严格单调递增&#xff0c;最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值&#xff0c;最小值左侧的数值严格单调递减&#xff0c;最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)

macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 &#x1f37a; 最新版brew安装慢到怀疑人生&#xff1f;别怕&#xff0c;教你轻松起飞&#xff01; 最近Homebrew更新至最新版&#xff0c;每次执行 brew 命令时都会自动从官方地址 https://formulae.…...