解释下什么是事件代理?应用场景?

news/2024/11/17 7:28:52/文章来源:https://www.cnblogs.com/smileZAZ/p/18199581

一、是什么

事件代理,俗地来讲,就是把一个元素响应事件(clickkeydown......)的函数委托到另一个元素

前面讲到,事件流的都会经过三个阶段: 捕获阶段 -> 目标阶段 -> 冒泡阶段,而事件委托就是在冒泡阶段完成

事件委托,会把一个或者一组元素的事件委托到它的父层或者更外层元素上,真正绑定事件的是外层元素,而不是目标元素

当事件响应到目标元素上时,会通过事件冒泡机制从而触发它的外层元素的绑定事件上,然后在外层元素上去执行函数

下面举个例子:

比如一个宿舍的同学同时快递到了,一种笨方法就是他们一个个去领取

较优方法就是把这件事情委托给宿舍长,让一个人出去拿好所有快递,然后再根据收件人一一分发给每个同学

在这里,取快递就是一个事件,每个同学指的是需要响应事件的 DOM元素,而出去统一领取快递的宿舍长就是代理的元素

所以真正绑定事件的是这个元素,按照收件人分发快递的过程就是在事件执行中,需要判断当前响应的事件应该匹配到被代理元素中的哪一个或者哪几个

二、应用场景

如果我们有一个列表,列表之中有大量的列表项,我们需要在点击列表项的时候响应一个事件

<ul id="list"><li>item 1</li><li>item 2</li><li>item 3</li>......<li>item n</li>
</ul>

如果给每个列表项一一都绑定一个函数,那对于内存消耗是非常大的

// 获取目标元素
const lis = document.getElementsByTagName("li")
// 循环遍历绑定事件
for (let i = 0; i < lis.length; i++) {lis[i].onclick = function(e){console.log(e.target.innerHTML)}
}

这时候就可以事件委托,把点击事件绑定在父级元素ul上面,然后执行事件的时候再去匹配目标元素

// 给父层元素绑定事件
document.getElementById('list').addEventListener('click', function (e) {// 兼容性处理var event = e || window.event;var target = event.target || event.srcElement;// 判断是否匹配目标元素if (target.nodeName.toLocaleLowerCase === 'li') {console.log('the content is: ', target.innerHTML);}
});

还有一种场景是上述列表项并不多,我们给每个列表项都绑定了事件

但是如果用户能够随时动态的增加或者去除列表项元素,那么在每一次改变的时候都需要重新给新增的元素绑定事件,给即将删去的元素解绑事件

如果用了事件委托就没有这种麻烦了,因为事件是绑定在父层的,和目标元素的增减是没有关系的,执行到目标元素是在真正响应执行事件函数的过程中去匹配的

举个例子:

下面html结构中,点击input可以动态添加元素

<input type="button" name="" id="btn" value="添加" />
<ul id="ul1"><li>item 1</li><li>item 2</li><li>item 3</li><li>item 4</li>
</ul>

使用事件委托

const oBtn = document.getElementById("btn");
const oUl = document.getElementById("ul1");
const num = 4;//事件委托,添加的子元素也有事件
oUl.onclick = function (ev) {ev = ev || window.event;const target = ev.target || ev.srcElement;if (target.nodeName.toLowerCase() == 'li') {console.log('the content is: ', target.innerHTML);}};//添加新节点
oBtn.onclick = function () {num++;const oLi = document.createElement('li');oLi.innerHTML = `item ${num}`;oUl.appendChild(oLi);
};

可以看到,使用事件委托,在动态绑定事件的情况下是可以减少很多重复工作的

三、总结

适合事件委托的事件有:clickmousedownmouseupkeydownkeyupkeypress

从上面应用场景中,我们就可以看到使用事件委托存在两大优点:

  • 减少整个页面所需的内存,提升整体性能
  • 动态绑定,减少重复工作

但是使用事件委托也是存在局限性:

  • focusblur这些事件没有事件冒泡机制,所以无法进行委托绑定事件

  • mousemovemouseout这样的事件,虽然有事件冒泡,但是只能不断通过位置去计算定位,对性能消耗高,因此也是不适合于事件委托的

如果把所有事件都用事件代理,可能会出现事件误判,即本不该被触发的事件被绑定上了事件

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/708320.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux/Golang/glibC系统调用

Linux/Golang/glibC系统调用 本文主要通过分析Linux环境下Golang的系统调用,以此阐明整个流程有时候涉略过多,反而遭到质疑~,写点文章证明自己实力也好Golang系统调用 找个函数来分析 https://pkg.go.dev/os/exec#Cmd.Wait 源码文件在src/os目录下的: exec.go -> exec_u…

[转帖]【全网首发】一些可以显著提高 Java 启动速度方法原创

https://heapdump.cn/article/4136322?from=pc 我们线上的业务 jar 包基本上普遍比较庞大,动不动一个 jar 包上百 M,启动时间在分钟级,拖慢了我们在故障时快速扩容的响应。于是做了一些分析,看看 Java 程序启动慢到底慢在哪里,如何去优化,目前的效果是大部分大型应用启动…

博客园美化:canvas炫酷背景

话不多说,先上效果图:yysy,这个当背景确实酷炫!!!😄 页脚HTML代码:1 <script src="https://files.cnblogs.com/files/zhonglinke/vendors.js"></script>2 <script type="text/javascript" language="javascript">3 4…

APC挂靠

5.APC挂靠 用户态apc 和上一课的内核apc几乎一致,唯一的变动就是这个 //插入当前线程KeInitializeApc(pKapc, eThread, OriginalApcEnvironment, KernelAPCRoutineFunc, NULL, 0x4011d0, UserMode, NULL);改成了UserMode函数地址改成了进程的地址0x4011d0 完整代码 Driver-mai…

Java(7)-Maven抽取公共模块构建jar包

前提假设:项目中有两个Moudle,分别是Moudle1和Moudle2,它们有些代码是相同的,比如相同的类和API,重复书写当然可以正常运行,但是我们可以用maven打包成jar包,其他Moudle直接引用即可。 步骤 1.新建一个Module-common pox.xml 中配置 Module1 和 Moudle2 同样使用的依赖:…

KPCR进程概念

1.KPCR进程概念 KPCR 介绍 KPCR 是CPU的控制结构 FS段寄存器在R0(FS=0x30)的时候指向KPCR结构 FS 段寄存器在R3(FS=0x3b)的时候指向 当前线程的TEB(线程) 线程结构是运行在CPU上面,所以线程结构是放在CPU上的 kd> dt _KPCR ntdll!_KPCR+0x000 NtTib : _NT_TIB…

驱动断链

03驱动断链获取驱动信息的途径是从Driver和FileSystem两个目录下获得的正常情况下我们自己做驱动遍历只能便利Driver下的所有驱动,也就是驱动链表里的驱动 分析 这里我们F12进去找一下DRIVER_OBJECT的结构 typedef struct _DRIVER_OBJECT *PDRIVER_OBJECT; WinDbg里dt一下 kd&…

蓝屏分析

04蓝屏分析 直接上蓝屏代码 #include <ntifs.h>VOID Unload(PDRIVER_OBJECT pDriver) {DbgPrint("Driver Unload\r\n"); }NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg) {pDriver->DriverUnload = Unload;//DbgBreakPoint();DbgPrin…

Qt学习第二篇(基本小组件的使用)

Qt_2 小部件是 GUI 的基本元素。 它也称为UI 控件。 它接受来自底层平台的不同用户事件,如鼠标和键盘事件(以及其他事件)。 我们使用不同的小部件创建 UI。 曾经有一段时间,所有的 GUI 控件都是从头开始编写的。 Qt 小部件通过开发具有现成的 GUI 控件的桌面 GUI 来缩短时间,…

Weblogic T3反序列化漏洞(CVE-2018-2628)

在Weblogic中RMI通信的实现是使用T3协议,并且在T3的传输过程中,和RMI一样,会进行序列化和反序列化的操作。目录前言T3协议概述漏洞复现修复方案 前言 WebLogic Server 是一个企业级的应用服务器,由Oracle公司开发,支持完整的Java EE规范,包括EJB、JSP、Servlet、JMS等,适…

方方方的数据结构

总算给我看懂到底是什么意思了。。。 首先我们来考虑按照时间+扫描线进行处理,假设操作如下黑色是加操作,黄色是乘操作,绿色是加操作,对于红色那条线所代表的点,随着时间的流逝,首先在刚刚进入黑色的时候,这一点的值就被加上了一个数,然后刚刚进入黄色的时候,这一点的…

手机硬件检测:-DeviceTest

手机硬件检测:Z-DeviceTest官方版是款针对手机硬件所打造的检测工具。手机硬件检测:Z-DeviceTest能够检测硬件和OS,硬件上不仅仅是电池、cpu、内存、OS,甚至连usb、扬声器、指南针、摄像头、GPS、听筒等都能检测。并且手机硬件检测:Z-DeviceTest还能够对市面众多的机型进行检…