概述:

通俗地来讲,就是把一个元素响应事件(click、keydown……)的函数委托另一个元素; 一般来讲,会把一个或者一组元素的事件委托到它的父层或者更外层元素上,真正绑定事件的是外层元素

事件委托的原理:

通过事件冒泡机制从而触发它的外层元素的绑定事件上,然后在外层元素上去执行函数

事件委托的优点:

1.可以大量节省内存占用

  • 示例1:需要给100个按钮添加点击事件?
  • 解决方法:就是监听这100个按钮的祖先,等冒泡的时候判断target是否是这100个按钮中的一个

首先,在HTML的body里新建一个id为div1的div,在里面添加100个按钮
下面是 JS 的代码:

  1. div1.addEventListener('click', (e) => {
  2. const t = e.target
  3. if (t.tagName.toLowerCase() === 'button') {
  4. console.log('button 被点击了')
  5. console.log('button内容是' + t.textContent)
  6. }
  7. })
  • e.target指的是被操作的元素

运行JS,每点击一下按钮,都会显示对应的内容,如下图:
浅析事件委托 - 图1

2.可以监听动态元素(还未生成的事件)

  • 示例2:对于一个还未生成的点击事件的监听
  • 解决办法是:先监听它的祖先,等到点击的时候再看是不是我们想要监听的事件 ```javascript // 1秒后在div1下创建一个button标签 setTimeout(()=>{ const button = document.createElement(‘button’) button.textContent = ‘click 1’ div1.appendChild(button) },1000)

div1.addEventListener(‘click’,(e)=>{ const t = e.target if(t.tagName.toLowerCase() === ‘button’){ console.log(‘button 被 click’) } }) `` 在button标签创建之后,再点击button,会打印出console.log()`里的内容

事件委托的缺点:

  1. 事件委托基于冒泡,对于不冒泡的事件不支持。
  2. 层级过多,冒泡过程中,可能会被某层阻止掉。
  3. 理论上委托会导致浏览器频繁调用处理函数,虽然很可能不需要处理。所以建议就近委托,比如在table上代理td,而不是在document上代理td。
  4. 把所有事件都用代理就可能会出现事件误判。比如,在document中代理了所有button的click事件,另外的人在引用改js时,可能不知道,造成单击button触发了两个click事件。