谈谈事件代理(事件委托)

101 阅读2分钟

事件代理

一、事件代理是什么

事件代理(事件委托),是把一个或者一组元素的事件委托到它的父层或者更外层元素上,真正绑定事件的是外层元素,而不是目标元素

事件流的三个阶段:捕获阶段 -> 目标阶段 -> 冒泡阶段,而事件委托就在冒泡阶段完成

当事件响应到目标元素上时,会通过事件冒泡机制从而触发它的外层元素的绑定事件上,然后在外层元素上去执行函数

举例理解 宿舍买饭,一个个去买方法就比较笨,可以让宿舍长买完宿舍所有人的饭
这个例子中,每个宿舍成员就是需要响应事件的DOM元素,代买饭的宿舍长就是代理元素

二、应用场景

实例一:动态响应事件

现有一个列表,列表之中有大量的列表项,我们需要在点击列表项的时候响应一个事件

<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
</ul>

传统给每个列表项一一都绑定一个函数,那对于内存消耗是非常大的

 //获取目标元素
 const lis = document.querySelectorAll('li')
 //循环绑定事件
  for (let i = 0; i < lis.length; i++) {
    lis[i].addEventListener('click', function (e) {
      console.log(e.target.innerHTML)
    })
  }

这时候就可以事件委托,把点击事件绑定在父级元素ul上面,然后执行事件的时候再去匹配目标元素

// 给父层元素绑定事件
 document.querySelector('ul').addEventListener('click', function (e) {
    if (e.target.tagName.toLowerCase() === 'li') {
      console.log(e.target.innerHTML) //输出为li的内容
    }
 })

实例二动态添加元素

<button>添加元素</button>
<ul>
  <li>1</li>
  <li>2</li>
  <li>3</li>
</ul>

      const btn = document.querySelector('button')
      const ul = document.querySelector('ul')
      let num = 3
      //业务:点击按钮,向ul中插入一个li,并页面展示
      btn.addEventListener('click', function () {
        const li = document.createElement('li')
        li.innerHTML = ++num
        ul.appendChild(li)
      })

可以看到,使用事件委托,在动态绑定事件的情况下是可以减少很多重复工作的

三、总结

适合事件委托的事件有:clickmousedownmouseupkeydownkeyup

事件委托存在两大优点:

  • 减少整个页面所需的内存,提升整体性能

  • 动态绑定,减少重复工作

但是使用事件委托也是存在局限性:

  • focusblur这些事件没有事件冒泡机制,所以无法进行委托绑定事件

  • mousemovemouseout这样的事件,虽然有事件冒泡,但是只能不断通过位置去计算定位,对性能消耗高,因此也是不适合于事件委托的