事件委托

155 阅读2分钟

为什么会有事件委托?

如果一个列表中有多个li,都需要绑定监听函数,用for循环能做到,但是性能不太好。还有就是目前不存在的元素怎么添加监听函数?用JS一直监听元素是否出现再绑定?那这样做的过程比较复杂,性能也差。
在JS中,添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能,因为需要不断的与dom节点进行交互,访问dom的次数越多,引起浏览器重绘与重排的次数也就越多,就会延长整个页面的交互就绪时间,这就是为什么性能优化的主要思想之一就是减少DOM操作的原因;如果要用事件委托,就会将所有的操作放到js程序里面,与dom的操作就只需要交互一次,这样就能大大的减少与dom的交互次数,提高性能

什么是事件委托?

事件委托、事件代理都是同一个东西。委托就是让他人帮你做你本应该做的事。比如说取快递的时候,委托驿站代收。事件委托就是子元素的事件监听委托给父元素、祖先元素监听。

原理

利用触发冒泡事件的原理,只指定一个事件处理程序,就可以管理某一类型的所有事件。一般就是一次性将父元素绑定事件,通过判断event.target 来执行相应的方法,后续添加子元素的时候不用再次绑定。

实现一

<body>
    <ul id="demo">
      <li>li1</li>
      <li>li2</li>
      <li>li3</li>
      <li>li4</li>
      <li>li5</li>
    </ul>
<script>
      demo.addEventListener("click", () => {
        console.log("没有给li绑定事件,但点击了li,都会执行demo的监听函数");
      });
</script>
</body>

但该实现有个问题,假如ul里面有其他元素呢?(其实ul里面最好只放li元素,可以想成div里面有多种元素,只想其中一种元素点击了才执行监听函数。)那么就需要加些代码判断了。

实现二

target:触发事件的元素
currentTarget:绑定了监听函数的元素
tagName:可获取元素的标签名
toLowerCase():将字符串转成小写形式 修改后的代码:

demo.addEventListener("click", (e) => {
      if (e.target.tagName.toLowerCase() === "li") {
          console.log("没有给li绑定事件,但点击了li,都会执行demo的监听函数");
      }
});

总结

我们可以发现事件委托还是挺简单的。原理利用了事件模型的冒泡机制,但是利用的过程中要考虑多方面的因素。