【前端】详解JavaScript变乱署理(变乱委托)

[复制链接]
发表于 2026-2-3 10:27:22 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
   😎 作者先容:我是步调员洲洲,一个热爱写作的非闻名步调员。CSDN全栈优质范畴创作者、华为云博客社区云享专家、阿里云博客社区专家博主。
🤓 同时接待各人关注其他专栏,我将分享Web前后端开辟、人工智能、呆板学习、深度学习从0到1系列文章。
🖥 随时接待您跟我沟通,一起交换,一起发展、进步!点此也可得到接洽方式~
  

媒介

变乱署理(Event Delegation),又称之为变乱委托。是JavaScript中常用绑定变乱的常用本领。
顾名思义,“变乱署理”便是把本来必要绑定在子元素的相应变乱(click、keydown…)委托给父元素,让父元素继续变乱监听的职务。


变乱署理的原理是DOM元素的变乱冒泡。
我们举一个平常的例子来举行分析:
比如一个宿舍的同砚同时快递到了,一种方法就是他们一个个去领取,尚有一种方法就是把这件事变委托给宿舍长,让一个人出去拿好全部快递,然后再根据收件人一 一分发给每个宿舍同砚。
在这里,取快递就是一个变乱,每个同砚指的是必要相应变乱的 DOM 元素,而出去同一领取快递的宿舍长就是署理的元素,以是真正绑定变乱的是这个元素,按照收件人分发快递的过程就是在变乱实行中,必要判断当前相应的变乱应该匹配到被署理元素中的哪一个大概哪几个。
一、变乱冒泡

在JavaScript编程中,变乱署理(Event Delegation)是一种将变乱监听器应用于一个父元素,而不是直策应用于每一个子元素的技能。


这种方法可以进步性能,尤其是在处理惩罚大量元素时。本文将具体先容变乱署理的概念、原理、利用场景、代码示例以及留意事项。
以是在相识变乱署理之前,我们必要知道什么是变乱冒泡(Event Bubbling)。
当一个变乱在DOM元素上触发时,它会起首在该元素上触发,然后逐级向上传播到文档的根元素。这个过程就是变乱冒泡。
变乱传播分成三个阶段:


  • 捕获阶段:从window对象传导到目标节点(上层传到底层)称为“捕获阶段”(capture phase),捕获阶段不会相应任何变乱;
  • 目标阶段:在目标节点上触发,称为“目标阶段”
  • 冒泡阶段:从目标节点传导回window对象(从底层传回上层),称为“冒泡阶段”(bubbling
    phase)。变乱署理便是利用变乱冒泡的机制把里层所必要相应的变乱绑定到外层;
变乱署理利用了变乱冒泡的原理。通过在父元素上设置监听器,可以捕获到在其子元素上触发的变乱。由于变乱会从子元素冒泡到父元素,以是父元素上的监听器可以处理惩罚这些变乱。
优点


  • 镌汰内存斲丧:不必要为每个子元素分别添加变乱监听器。
  • 进步性能:特殊是在动态天生的元素上,不必要为新元素重新绑定变乱。
  • 简化代码:同一处理惩罚变乱,代码更轻便。
我们通过代码来看看优点:可以大量节省内存占用,镌汰变乱注册,比如在ul上署理全部li的click变乱。
  1. <ul id="myList">
  2.     <li>列表项 1</li>
  3.     <li>列表项 2</li>
  4.     <li>列表项 3</li>
  5.     <!-- 更多列表项 -->
  6. </ul>
复制代码
如上面代码所示,如果给每个li列表项都绑定一个函数,那对内存的斲丧黑白常大的,因此较好的办理办法就是将li元素的点击变乱绑定到它的父元素ul身上,实行变乱的时间再去匹配判断目标元素。
假设上述的例子中列表项li就几个,给每个列表项都绑定了变乱。
但是在很多时间,必要通过 AJAX 大概用户利用动态的增长大概删除列表项li元素,那么在每一次改变的时间都必要重新给新增的元素绑定变乱,给即将删去的元素解绑变乱。
如果用了变乱委托就没有这种贫困了,由于变乱是绑定在父层的,和目标元素的增减是没有关系的,实行到目标元素是在真正相应实行变乱函数的过程中去匹配的;以是利用变乱在动态绑定变乱的情况下是可以镌汰很多重复工作的。
缺点


  • 变乱范例限定:只能捕获冒泡的变乱,不能捕获不冒泡的变乱。
  • 变乱对象处理惩罚:必要通过变乱对象的属性来确定变乱的真正泉源。
二、代码实现

2.1 JavaScript原生实现

  1. <ul id="myLinks">
  2.   <li id="goSomewhere">Go somewhere</li>
  3.   <li id="doSomething">Do something</li>
  4.   <li id="sayHi">Say hi</li>
  5. </ul>
复制代码
必要像下面如许为它们添加 3 个事 件处理惩罚步调:
  1.     var item1 = document.getElementById("goSomewhere");
  2.     var item2 = document.getElementById("doSomething");
  3.     var item3 = document.getElementById("sayHi");
  4.     item1.onclick = function() {
  5.       location.href = "http://www.baidu.com";
  6.     };
  7.     item2.onclick = function() {
  8.       document.title = "事件委托";
  9.     };
  10.     item3.onclick = function() {
  11.       alert("hi");
  12.     };
复制代码
如果在一个复杂的 Web 应用步调中,对全部可单击的元素都接纳这种方式,那么效果就会有数不 清的代码用于添加变乱处理惩罚步调。
此时,可以利用变乱委托技能办理这个题目。
利用变乱委托,只需在 DOM 树中只管最高的条理上添加一个变乱处理惩罚步调,如下所示:
  1.     var item1 = document.getElementById("goSomewhere");
  2.     var item2 = document.getElementById("doSomething");
  3.     var item3 = document.getElementById("sayHi");
  4.     document.addEventListener("click", function (event) {
  5.       var target = event.target;
  6.       switch (target.id) {
  7.         case "doSomething":
  8.           document.title = "事件委托";
  9.           break;
  10.         case "goSomewhere":
  11.           location.href = "http://www.baidu.com";
  12.           break;
  13.         case "sayHi": alert("hi");
  14.           break;
  15.       }
  16.     })
复制代码
大概代码:
  1. document.getElementById('myList').addEventListener('click', function(event) {
  2.     if (event.target.tagName === 'LI') {
  3.         console.log('你点击了:', event.target.textContent);
  4.     }
  5. });
复制代码
2.2 jQuery变乱delegate()实现

delegate() 方法为指定的元素(属于被选元素的子元素)添加一个或多个变乱处理惩罚步调,并规定当这些变乱发生时运行的函数。
格式:$(selector).delegate(childSelector, event, data, function)
childSelector:必须,规定要附加变乱处理惩罚步调的一个或多个子元素。
event:必须,规定附加到元素的一个或多个变乱。由空格分隔多个变乱值。必须是有效的变乱。
data:可选,规定通报到函数的额外数据。
function:必须,规定当变乱发生时运行的函数。
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.   <meta charset="utf-8">
  5.   <script src="http://lib.sinaapp.com/js/jquery/2.0.2/jquery-2.0.2.min.js"></script>
  6. </head>
  7. <body>
  8.   <ul id="myLinks">
  9.     <li id="goSomewhere">Go somewhere</li>
  10.     <li id="doSomething">Do something</li>
  11.     <li id="sayHi">Say hi</li>
  12.   </ul>
  13.   <script>
  14.     $(document).ready(function () {
  15.       $("#myLinks").delegate("#goSomewhere", "click", function () {
  16.         location.href = "http://www.baidu.com";
  17.       });
  18.     });
  19.   </script>
  20. </body>
  21. </html>
复制代码
2.3 动态添加元素

  1. function addItem() {
  2.     var newItem = document.createElement('li');
  3.     newItem.textContent = '新列表项';
  4.     document.getElementById('myList').appendChild(newItem);
  5. }
  6. // 即使使用事件代理,新添加的列表项也会有点击事件
  7. addItem();
复制代码
三、实战案例分析

假设我们有一个图片库,用户点击任何图片时,必要体现图片的形貌:
  1. <div id="gallery">
  2.     <img src="image1.jpg" alt="图片1" title="这是图片1的描述">
  3.     <img src="image2.jpg" alt="图片2" title="这是图片2的描述">
  4.     <!-- 更多图片 -->
  5. </div>
复制代码
利用变乱署理,我们可以如许实现:
  1. document.getElementById('gallery').addEventListener('click', function(event) {
  2.     if (event.target.tagName === 'IMG') {
  3.         alert(event.target.title);
  4.     }
  5. });
复制代码
四、留意事项

变乱范例:确保利用的变乱范例支持冒泡,如 click、mouseover 等。
变乱委托链:制止在多个元素上设置雷同范例的变乱署理,这大概导致变乱处理惩罚逻辑紊乱。
变乱对象:精确利用 event.target 或 event.currentTarget 来区分变乱的泉源。
性能思量:固然变乱署理可以镌汰内存斲丧,但在某些情况下,如变乱处理惩罚逻辑非常复杂,大概会影响性能。
兼容性:变乱署理在全部当代欣赏器中都得到支持,但在老旧欣赏器中大概存在题目。
总结

📝社群方向很多,相干范畴有Web全栈(前后端)、人工智能、呆板学习、自媒体副业交换、前沿科技文章分享、论文精读等等。

回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表