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

js中和Vue中的事件委托(事件代理)的实现方法

目录

一、事件委托(事件代理)

1、事件委托的优点

2、事件委托的缺点

3、为什么要使用事件委托

4、事件委托实现原理

5、DOM事件流

6、事件委托的实现方法

1、vue写法

1.1、html代码

1.2、js代码

2、原生的写法其实也差不多:

2.1、html代码

2.2、js代码

二、阻止事件冒泡

三、取消默认事件

四、总结


一、事件委托(事件代理)

将原本需要绑定在子元素上的事件监听器委托在父元素上,让父元素充当事件监听的职务。

利用事件冒泡的特性,在父节点上响应事件,而不是在子节点上响应事件的技术。它能够改善性能,因为只需要在父元素上设置一次事件监听器,就可以管理同一类型的所有子元素的事件。

即事件从最深的节点开始,逐步向上传播。在事件冒泡过程中,父元素会捕获到子元素的事件,并进行分析。通过查看event对象的属性,可以确定是哪个子元素的事件,从而执行相应的处理逻辑。

使用事件委托能够避免对每个子元素单独设置事件监听器,降低了与DOM交互的次数,提高了页面的整体运行性能。同时,事件委托也具有更高的灵活性和可维护性,不需要操作大量的DOM元素。

在Vue中,可以利用v-on指令或@符号来绑定事件监听器,并在父元素上设置事件委托。例如,可以在父元素上设置一个click事件监听器,然后在子元素上绑定一个click事件,通过事件委托实现父元素对子元素事件的响应。


1、事件委托的优点
  • 节省内存(dom与js的关联),减少事件的注册
  • 增加子元素也无需再注册事件
2、事件委托的缺点

获取绑定的节点数据会相对麻烦一点

3、为什么要使用事件委托

在日常开发中,很经常我们会遇到个问题,就是在长列表数据较多的时候,而又需要对子元素注册一些事件(如onClick),就会造成比较大的内存开支,很耗费性能,也可能会造成页面卡顿等等;
所以可以通过在父元素上添加@click监听,而不是在子元素上注册事件;
如果数据量比较少,就可忽略不计;

此外,事件处理程序需要与 DOM 节点进行交互,访问 DOM 的次数越多,引起浏览器重绘和重排的次数也就越多,从而影响页面的性能。

4、事件委托实现原理

事件委托是利用事件的冒泡原理来实现的,大致可以分为三个步骤:

  1. 确定要添加事件元素的父级元素;
  2. 给父元素定义事件,监听子元素的冒泡事件;
  3. 使用 event.target 来定位触发事件冒泡的子元素。

5、DOM事件流

事件流描述的是从页面中接收事件的顺序。事件发生时会在元素节点之间按照特定的顺序传播,这个传播过程即DOM事件流。

比如:我们给页面中的一个div注册了单击事件,当你单击了div时,也就单击了body,单击了html,单击了document。


DOM 事件流会经历3个阶段:

  • 捕获阶段:事件从文档的根节点流向目标对象。

事件从最不精确的对象(document 对象)开始触发,然后到最精确(也可以在窗口级别捕获事件,不过必须由开发人员特别指定),与事件冒泡相反,事件会从最外层开始发生,直到最具体的元素。

  • 当前目标阶段:在目标对象上被触发。
  • 冒泡阶段:回溯到文档的根节点。

微软提出了名为事件冒泡的事件流。事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发。

6、事件委托的实现方法

1、vue写法
1.1、html代码
<div id="app"><div id="event-agent" @click="eventAgent"><p v-for="(item, index) in list" :key="index" :data-name="item.name" :data-index="index">{{item.name}}</p></div>
</div>

> 获取节点参数 (data-index、data-name),则在 $event.target.dataset  { index: 'xxx', name: 'xxx' } 中取值

1.2、js代码
data() {return { list: [{ id: 1, name: 'kmj1'},{ id: 2, name: 'kmj2'},{ id: 3, name: 'kmj3'},{ id: 4, name: 'kmj4'}]   }
},
methods: { // 事件委托eventAgent(e) {const target = e.target; console.log(target )// 注意 e.target.nodeName 的元素名是大写的if (target  && target.nodeName === "P") {const dataset = target .dataset;console.log('$event.target.dataset : ' dataset ); // $event.target.dataset :  { name: 'xxx', index: 'xxx' }}}
}
2、原生的写法其实也差不多:
2.1、html代码
<div id="event-agent"><p :data-name="Item1" :data-index="0">Item 1</p><p :data-name="Item2" :data-index="1">Item 2</p><p :data-name="Item3" :data-index="2">Item 3</p><p :data-name="Item4" :data-index="3">Item 4</p><p :data-name="Item5" :data-index="4">Item 5</p><p :data-name="Item6" :data-index="5">Item 6</p>
</div>
2.2、js代码
document.getElementById( "event-agent").onclick = function(event){ // 兼容Ie的写法event = event || window.event;var  target = event.target || event.srcElement;  // 注意 e.target.nodeName 的元素名是大写的if (target  && target.nodeName === "P") {const dataset = target .dataset;console.log('$event.target.dataset : ' dataset ); // $event.target.dataset :  { name: 'xxx', index: 'xxx' }}
}; // 也可以用这种方式,其实都差不多的:
// 冒泡阶段处理程序  
document.getElementById( "event-agent").addEventListener( "click", (e) => {},   false);
// 捕获阶段处理程序
document.getElementById( "event-agent").addEventListener( "click", (e) => {},   true);


二、阻止事件冒泡

W3C的方法是e.stopPropagation(),IE则是使用e.cancelBubble = true。 stopPropagation是事件的一个方法,作用是阻止目标元素的事件冒泡,但是不会组织默认行为。


 

function stopBubble(e) { 
//如果提供了事件对象,则这是一个非IE浏览器 
if ( e && e.stopPropagation ) //因此它支持W3C的stopPropagation()方法 e.stopPropagation(); 
else //否则,我们需要使用IE的方式来取消事件冒泡 window.event.cancelBubble = true; 
}

三、取消默认事件

W3C的方法是e.preventDefault(),IE则是使用e.returnValue = false。 preventDefault()是事件对象(Event)的一个方法,作用是取消一个目标元素的默认行为。既然是默认行为,那么元素必须有默认行为才能被取消,如果元素本身就没有默认行为,调用自然就无效了。什么元素有默认行为呢?如链接\<a href="">,提交按钮<input type=”submit”>等,这些都有默认行为。


 

function preventDefault(e){if(e && e.preventDefault){e.preventDefault();}else{window.event.returnValue = false;}return false;
}


 


四、总结

要使用事件委托,需要保证事件能够发生冒泡,适合使用事件委托的事件有 click、mousedown、mouseup、keydown、keyup、keypress 等。需要注意的是,虽然 mouseover 和 mouseout 事件也会发生事件冒泡,但处理起来非常麻烦,所以不推荐在 mouseover 和 mouseout 事件中使用事件委托。

另外,对于不会发生事件冒泡的事件(例如 load、unload、abort、focus、blur 等),则无法使用事件委托。

相关文章:

js中和Vue中的事件委托(事件代理)的实现方法

目录 一、事件委托&#xff08;事件代理&#xff09; 1、事件委托的优点 2、事件委托的缺点 3、为什么要使用事件委托 4、事件委托实现原理 5、DOM事件流 6、事件委托的实现方法 1、vue写法 1.1、html代码 1.2、js代码 2、原生的写法其实也差不多&#xff1a; 2.1、…...

C++学习笔记——对象的指针

目录 一、对象的指针 二、减少对象的复制开销 三、应用案例 游戏引擎 图像处理库 数据库管理系统 航空航天软件 金融交易系统 四、代码的案例应用 一、对象的指针 是一种常用的技术&#xff0c;用于处理对象的动态分配和管理。使用对象的指针可以实现以下几个方面的功…...

QT5.14 实现ModbusTCP客户端 Demo

本文在QT5.14平台&#xff0c;基于QModbusClientTcp类&#xff0c;实现了客户端对单个寄存器的读写&#xff0c;用ModbusSlave做服务器做测试。 1.界面 (1)更改读按钮的名称为bt_Read (2)更改写按钮的名称为bt_Write 2.修改pro文件的第三行 greaterThan(QT_MAJOR_VERSION, 4)…...

c++析构函数

析构函数的简述 1. 析构函数和构造函数类似&#xff0c;是c规定当对象的生命周期结束时&#xff0c;默认你会调用析构函数。 2. 同理&#xff0c;当我们不写析构函数的时候&#xff0c;编译器会自动生成一个空实现的析构函数。 3. 析构函数只能编译器自己调用&#xff0c;我们…...

nodejs 服务端token 高效缓存验证

在前后端分离开发过程中,经常涉及权限验证的问题,一般都是采用由服务端根据前端传递的用户名和密码,验证成功后生成token,然后前端在访问服务端接口时,再附带token访问。 如果服务端高频次的解析token,进行内容验证,则会大大降低接口性能,而采用内存或者redis进行合法…...

C++内存管理机制(侯捷)笔记2

C内存管理机制&#xff08;侯捷&#xff09; 本文是学习笔记&#xff0c;仅供个人学习使用。如有侵权&#xff0c;请联系删除。 参考链接 Youtube: 侯捷-C内存管理机制 Github课程视频、PPT和源代码: https://github.com/ZachL1/Bilibili-plus 下面是第二讲allocator具体实…...

java基础之异常练习题

异常 1.Java 中所有的错误/异常都继承自 Throwable类&#xff1b;在该类的子类中&#xff0c; Error 类表示严重的底层错误&#xff0c; 对于这类错误一般处理的方式是 直接报告并终止程序 &#xff1b; Exception 类表示异常。 2.查阅API&#xff0c;完成以下填空&#xff1a;…...

智慧旅游景区解决方案:PPT全文49页,附下载

关键词&#xff1a;智慧景区建设&#xff0c;智慧旅游平台&#xff0c;智慧旅游运营检测系统项目&#xff0c;智慧文旅&#xff0c;智慧景区开发与管理&#xff0c;智慧景区建设核心&#xff0c;智慧景区开发与管理 一、智慧景区建设现状 1、基础设施建设&#xff1a;智慧景区…...

Demo: 给图片添加自定义水印并下载

给图片添加自定义水印并下载 <template><div class"wrap"><div class"optea"><div class"file-upload"><p>选择图片</p><el-button type"text" style"color: #c00;"><label f…...

黑马苍穹外卖学习Day5

文章目录 Redis学习Redis简介准备工作Redis常用数据类型介绍各数据类型的特点Redis常用命令字符串操作命令哈希操作命令列表操作命令集合操作命令有序集合操作命令通用操作命令 在Java中操作Redis导入Spring Data Redis坐标配置Redis数据源编写配置类&#xff0c;创建RedisTemp…...

【.NET Core】可为null类型详解

【.NET Core】可为null类型详解 文章目录 【.NET Core】可为null类型详解一、概述二、可为空的值类型2.1 声明和赋值2.2 检查可为空值类型2.3 基础类型与可为空的值类型互换2.4 可为空的值类型装箱和取消装箱2.5 如何确定可为空的值类型 三、可为 null 的引用类型 一、概述 nu…...

基于知识图谱的健康知识问答系统

基于知识图谱的健康知识问答系统 引言数据集与技术选型数据集技术选型 系统功能与实现数据导入与图数据库构建问答任务设计与实现1. 实体提取2. 用户意图识别 前端聊天界面与问答系统 结语 引言 随着互联网的发展&#xff0c;人们对健康知识的需求逐渐增加。为了更方便地获取健…...

橘子学K8S03之容器的理解

前面我们知道了容器是通过对一个普通的linux进程进行隔离和限制实现的一种特殊视角下的进程表现。而隔离和限制的实现技术分别是"Namespace"和“Cgroups”,在这两种机制的控制下&#xff0c;我们需要知道容器的本质是一种特殊的进程。 我们现在有了这个认知之后&…...

算法第十二天-矩形区域不超过K的最大数值和

矩形区域不超过K的最大数值和 题目要求 解题思路 来自[宫水三叶] 从题面来看显然是一道[二维前缀和]的题目。本题预处理前缀和的复杂度为O(m* n) 搜索所有子矩阵需要枚举[矩形左上角]和[矩形右下角]&#xff0c;复杂度是 O ( m 2 ∗ n 2 ) O(m^2 * n^2) O(m2∗n2)&#xff0c…...

【js】js数组对象去重:

文章目录 一、Map()二、对象访问属性的方法三、indexOf()四、双层for循环 let arrObj [{ name: "小红", id: 1 },{ name: "小橙", id: 1 },{ name: "小黄", id: 4 },{ name: "小绿", id: 3 },{ name: "小青", id: 1 },{ na…...

python高校舆情分析系统+可视化+情感分析 舆情分析+Flask框架(源码+文档)✅

毕业设计&#xff1a;2023-2024年计算机专业毕业设计选题汇总&#xff08;建议收藏&#xff09; 毕业设计&#xff1a;2023-2024年最新最全计算机专业毕设选题推荐汇总 &#x1f345;感兴趣的可以先收藏起来&#xff0c;点赞、关注不迷路&#xff0c;大家在毕设选题&#xff…...

Phaser详解

Phaser是一个相对较新且功能强大的同步原语&#xff0c;它于Java 7中引入&#xff0c;用于协调并行任务的执行。与CyclicBarrier和CountDownLatch等传统的同步工具相比&#xff0c;Phaser提供了更灵活和更高级的功能&#xff0c;特别是在处理动态和可变的并行任务集合时。 1.P…...

2个nodejs进程利用redis 实现订阅发布

1.新建文件 redis_db.js use strict;const redis require(redis); const options {host: "127.0.0.1",port: 6379,password: "123456", // CONFIG SET requirepass "123456" }var array [] for(var i0; i<3; i){const client redis.crea…...

LeetCode——2397. 被列覆盖的最多行数

通过万岁&#xff01;&#xff01;&#xff01; 题目&#xff1a;给你一个二维数组&#xff0c;然后里面是0和1&#xff0c;然后让你从里面选择numSelect列&#xff0c;使得去掉选择的列以后不存在1的行的数量最少。思路&#xff1a; 看到这个题目&#xff0c;本来以为是每一列…...

java通过HttpClient方式实现https请求的工具类(绕过证书验证)

目录 一、引入依赖包二、HttpClient方式实现的https请求工具类三、测试类 一、引入依赖包 引入相关依赖包 <!--lombok用于简化实体类开发--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><option…...

TongWEB(东方通)实战:从零部署企业级WEB前后端项目

1. 环境准备&#xff1a;银河麒麟系统下的基础搭建 在银河麒麟桌面系统V10(SP1)兆芯版上部署企业级WEB项目&#xff0c;环境准备是第一步。我遇到过不少开发者直接跳过环境检查就急着部署&#xff0c;结果浪费大量时间排查兼容性问题。这里分享几个关键点&#xff1a; 首先是系…...

别再只盯着wx.login了!SpringBoot后端实战:用getPhoneNumber接口搞定小程序用户手机号绑定

微信小程序用户手机号绑定&#xff1a;SpringBoot后端深度实践指南 在当今移动互联网生态中&#xff0c;微信小程序已成为连接用户与服务的重要桥梁。对于需要强实名认证或直接触达用户的业务场景&#xff08;如电商交易、金融服务、政务办理等&#xff09;&#xff0c;仅依赖w…...

终极免费Switch模拟器yuzu:解决电脑玩任天堂游戏的5大痛点

终极免费Switch模拟器yuzu&#xff1a;解决电脑玩任天堂游戏的5大痛点 【免费下载链接】yuzu 任天堂 Switch 模拟器 项目地址: https://gitcode.com/GitHub_Trending/yu/yuzu 想在电脑上畅玩Switch游戏却总是遇到各种问题&#xff1f;yuzu模拟器作为全球最受欢迎的开源任…...

STM32CubeIDE实战指南:从代码编译到一键下载的完整流程解析

1. STM32CubeIDE开发环境概述 对于刚接触STM32开发的工程师来说&#xff0c;选择一款合适的集成开发环境(IDE)至关重要。STM32CubeIDE是ST官方推出的免费开发工具&#xff0c;它集成了代码编辑、编译、调试和下载功能于一体&#xff0c;特别适合新手快速上手。我在实际项目中使…...

碧蓝航线自动化脚本:让游戏管理变得轻松高效

碧蓝航线自动化脚本&#xff1a;让游戏管理变得轻松高效 【免费下载链接】AzurLaneAutoScript Azur Lane bot (CN/EN/JP/TW) 碧蓝航线脚本 | 无缝委托科研&#xff0c;全自动大世界 项目地址: https://gitcode.com/gh_mirrors/az/AzurLaneAutoScript 你是否厌倦了每天重…...

Scarab空洞骑士模组管理器:2024年最完整的安装与使用指南

Scarab空洞骑士模组管理器&#xff1a;2024年最完整的安装与使用指南 【免费下载链接】Scarab An installer for Hollow Knight mods written with Avalonia. 项目地址: https://gitcode.com/gh_mirrors/sc/Scarab 还在为空洞骑士模组安装的复杂流程而烦恼吗&#xff1f…...

别再为嵌入式设备大内存发愁了!手把手教你用CMA(连续内存分配器)搞定Linux视频编解码缓冲区

嵌入式多媒体开发中的连续内存优化实战&#xff1a;CMA技术深度解析 在嵌入式多媒体开发领域&#xff0c;视频编解码、图像处理等任务对内存管理提出了严苛要求。当你在树莓派上部署视频监控系统&#xff0c;或在工业摄像头中实现实时H.264编码时&#xff0c;是否经常遇到这样的…...

VS Code光标主题定制指南:提升开发效率与视觉舒适度

1. 项目概述&#xff1a;一个为开发者量身定制的光标主题集合如果你和我一样&#xff0c;每天有超过8个小时的时间是在代码编辑器里度过的&#xff0c;那么你一定对那个在屏幕上闪烁的光标再熟悉不过了。它不仅仅是文本插入点&#xff0c;更是我们思维在数字世界中的延伸。然而…...

面试鸭:程序员面试备战工作台,构建结构化知识图谱与智能复习系统

1. 项目概述&#xff1a;一个面向求职者的“面试鸭”最近在技术社区里&#xff0c;看到不少朋友在讨论一个叫“mianshiya”的开源项目。乍一看这个名字&#xff0c;还以为是哪个美食博主分享的菜谱。点进去才发现&#xff0c;这其实是一个为程序员&#xff0c;特别是正在准备面…...

MCP服务器自动发现与管理工具mcpfinder详解

1. 项目概述&#xff1a;一个用于发现与管理MCP服务器的工具如果你正在构建或使用基于模型上下文协议&#xff08;Model Context Protocol&#xff0c; 简称MCP&#xff09;的应用&#xff0c;那么你很可能遇到过这样的困扰&#xff1a;手头有几个不同功能的MCP服务器&#xff…...