事件委托

1.什么是事件委托?

事件委托也叫事件代理,是一种重要的性能优化的手段。事件委托是利用事件的冒泡特性,把多个子元素的同一类型的监听逻辑,合并到父元素上通过一个监听函数来管理的行为,就是事件委托。

简单来讲,就是利用冒泡特性,把内层元素的事件委托给外层处理。

一个事件触发后,会在子元素和父元素之间传播。这种传播分成三个阶段。
(1)捕获阶段:从window对象传导到目标节点(上层传到底层)称为“捕获阶段”,捕获阶段不会响应任何事件;
(2)目标阶段:在目标节点上触发,称为“目标阶段”
(3)冒泡阶段:从目标节点传导回window对象(从底层传回上层),称为“冒泡阶段”。事件代理即是利用事件冒泡的机制把里层所需要响应的事件绑定到外层。

2.事件委托的优点

  • 可以大量节省内存占用,减少事件注册

例子

给每个li执行点击事件

<ul id="ul1">
   <li a='1231dd' id="1" class="1.1">111</li>
   <li>222</li>
   <li>333</li>
   <li>444</li>
</ul>

传统方式

  1. 获取ul
  2. 通过获取到ul去获取下面的所有li
  3. 循环li的长度,依次去注册事件
window.onload = function () {
    var oUl = document.getElementById("ul1");
    var oLi = oUl.getElementsByTagName('li');
    for (let i = 0; i < oLi.length; i++) {
        oLi[i].onclick = function () {
            console.log(i, oLi[i]);
        }
    }
}

事件委托

这里用父级ul做事件处理,当li被点击时,由于冒泡原理,事件就会冒泡到ul上,因为ul上有点击事件,所以事件就会触发,当然,这里当点击ul的时候,也是会触发的,那么问题就来了,如果我想让事件代理的效果跟直接给节点的事件效果一样怎么办,比如说只有点击li才会触发
Event对象提供了一个属性叫target,可以返回事件的目标节点,我们成为事件源,也就是说,target就可以表示为当前的事件操作的dom,但是不是真正操作dom,当然,这个是有兼容性的,标准浏览器用ev.target,IE浏览器用event.srcElement,此时只是获取了当前节点的位置,并不知道是什么节点名称,这里我们用nodeName来获取具体是什么标签名,这个返回的是一个大写的,我们需要转成小写再做比较(习惯问题)。

oUl.onclick = function (ev) {
     var ev = ev || window.event
     var target = ev.target || ev.srcElement
     if (target.nodeName.toLowerCase() === 'li') {
         console.dir(target);
     }
     // console.log(target.nodeName.toLowerCase(), ev);
}
  • 加了个判断,只会nodeName===li才会有效果,不会影响其他。

事件委托的方式,新添加的子元素是带有事件效果的,我们可以发现,当用事件委托的时候,根本就不需要去遍历元素的子节点,整体只注册一次ul事件,并没有给每个li都注册个监听。这样可以大大的减少dom操作,这就是事件委托的意义。

 

posted @ 2025-03-04 16:15  时光独醒  阅读(75)  评论(0)    收藏  举报