首页 > 其他分享 >解释下什么是事件代理?应用场景?

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

时间:2024-07-04 15:57:41浏览次数:20  
标签:解释 绑定 target 委托 元素 代理 item 场景 事件

一、是什么

事件代理,俗地来讲,就是把一个元素响应事件(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这样的事件,虽然有事件冒泡,但是只能不断通过位置去计算定位,对性能消耗高,因此也是不适合于事件委托的

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

标签:解释,绑定,target,委托,元素,代理,item,场景,事件
From: https://blog.csdn.net/lh20_02/article/details/140180350

相关文章

  • 进程D 状态的产生及原因解释
    在Linux系统中,进程的D状态表示进程处于不可中断的睡眠状态(UninterruptibleSleep)。这种状态通常由进程等待某些资源或事件引起,这些资源或事件无法立即可用。以下是一些常见的导致进程进入D状态的原因:I/O操作:等待磁盘I/O完成:进程可能正在等待磁盘读取或写入操作......
  • 火山引擎数据飞轮实践:在电商场景中,如何建设全链路数据血缘?
    数据作为新型生产要素,正支撑企业的数智化转型。但企业数字化建设也存在管理成本高、数据产品使用门槛高、数据资产价值不够的问题,其原因在于业务和数据之间没有形成双向良性驱动。 结合新时代企业数字化转型需求,火山引擎基于字节跳动十余年数据驱动的实践经验,对外发布企业数智......
  • C++单例模式、工厂模式、观察者模式等的实现和应用场景。
    设计模式是软件开发中常用的解决方案,它们提供了一些经过验证的方法来解决常见的设计问题。以下是单例模式、工厂模式和观察者模式在C++中的实现和应用场景的详细讲解。1.单例模式(SingletonPattern)概念单例模式确保一个类只有一个实例,并提供一个全局访问点来访问这个实例。......
  • 初识布隆过滤|工作场景
    作用检查一个元素是否在一个集合中优缺点优点:空间效率和查询时间比一般算法好,时间复杂度低,O(k)k是函数的个数,节省空间缺点:有一定的错误几率,没有的也可能判定为存在,删除困难,无法获得参数本身场景解决Redis缓存穿透问题邮件过滤,使用布聋过滤器来做邮件黑名单过滤堆爬虫......
  • 异步编程场景
    异步模型概述异步编程的核心是 Task 和 Task<T> 对象,这两个对象对异步操作建模。它们受关键字 async 和 await 的支持。在大多数情况下模型十分简单:对于I/O绑定代码,等待一个在 async 方法中返回 Task 或 Task<T> 的操作。对于CPU绑定代码,等待一个使用 ......
  • ssh 定时任务 的时间表示解释 cronExpression
    1.cron表达式格式:{秒数}{分钟}{小时}{日期}{月份}{星期}{年份(可为空)}2.cron表达式各占位符解释:{秒数}==>允许值范围:0~59,不允许为空值,若值不合法,调度器将抛出SchedulerException异常"*"代表每隔1秒钟触发;","代表在指定的秒数触发,比如"0,15,45"代表0秒、15秒和45......
  • Python - 各类路径盘点:interpreter解释器路径,lib路径
    interpreter解释器安装路径1.Windows操作系统:在Windows上,Python库通常安装在Python解释器的安装目录下的Lib\site-packages文件夹中。例如,默认情况下Python3.8的安装目录为”C:\Python38″,则库将安装在”C:\Python38\Lib\site-packages”文件夹中。2.macOS操作系统:在macOS......
  • 高并发场景下的热点key问题探析与应对策略
    目录一、问题描述二、发现机制三、解决策略分析 (一)解决策略一:多级缓存策略客户端本地缓存代理节点本地缓存 (二)解决策略二:多副本策略 (三)解决策略三:热点Key拆分与动态分散四、总结干货分享,感谢您的阅读!在高并发场景下,缓存作为前置查询机制,显著减轻了数据库的压......
  • Acore_characters数据库全面解释
    acore_characters数据库目前有95个表,主要存储与用户账户有关的信息。account_data包含有关客户账户和设置的数据。accountId玩家账户ID。typeValueDescription0全局-账户配置缓存2全局-账户绑定缓存4全局-账户巨集缓存time最后修改的时间。data未......
  • Acore_auth数据库全面解释
    简单说吧,如果你不会源码修改编译,单单玩数据库和DBC就能做出很有特色的端。Azerothcore的数据库是Mysql,所以你得下载个SQL管理工具,大家比较常用的是NavicatSQL,我常用的是HeidiSQL(免费)。连接数据库的话,地址、用户名和密码请自行查找服务端内的worldserver.conf文件,示例:LoginDataba......