持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情
前情提要
什么是事件委托?
事件委托又称事件代理。是指将自身的事件委托给上级处理。即:子级将事件委托给父级来处理。
实现原理:是基于Event Flow中的事件冒泡。当子级成为事件的起源的时候,就会通过事件传播一级一级向上进行冒泡。然后父级监听到该事件后就进行相应的逻辑处理。
应用场景:主要是用在原生js中的dom的增删改。比如在一个列表中,你需要进行新增行或者删除行。又或者在一个列表中你需要获取选中的行的数据。一般的实现思路是在列表中的每个子级绑定一个方法。该方法如果是获取信息,那就可以直接获取。如果是删除,那就需要获取父级的dom,然后调用removeChild方法来删除节点。这种方法,假如列表中有一万个节点,那么就会注册一万个相同的事件句柄。这显然是不合理的,并且对性能也不太友好。
针对上面频繁创建事件句柄该怎么处理呢?这个时间就用到了事件代理。如果我们把列表中的每个子节点的事件都取消。只给父级绑定一个事件。然后当子节点触发事件后,通过事件冒泡触发父级节点注册的事件,最后执行。此时无论子节点有一万个还是十万个哪怕千万个,也只创建了一个事件句柄。对性能友好。
具体代码实现
具体实现增删改就不做过多的敖述了。只展示最基本的查的功能,以此来做个对比。
老版本的方法
<div id="container"> <p class="item">1</p> <p class="item">2</p> <p class="item">3</p></div><script>function handle(e) { console.log(e)}for (let key of document.getElementsByClassName('item')) {key.addEventListener('click', handle)}</script>
使用事件代理
<div id="container"> <p>1</p> <p>2</p> <p>3</p></div><script>function handle(e) { console.log(e)}document.getElementById('container').addEventListener('click', handle);</script>
总结
从上述的两个案例可以看出相比较于在子节点绑定事件使用事件委托将自身事件通过事件冒泡委托给自己的父级来处理可以具有更优的性能,更少的代码量。
该事件委托的方式不仅仅适用于原生js,同样适用于当前主流的前端框架的数据驱动页面。具体实现,可自行尝试呦。
原文:https://juejin.cn/post/7101716250803306532