事件委托

194 阅读2分钟
  • 基本概念 事件委托,通俗地来讲,就是把一个元素响应事件(clickkeydown......)的函数委托到另一个元素;

一般来讲,会把一个或者一组元素的事件委托到它的父层或者更外层元素上,真正绑定事件的是外层元素,当事件响应到需要绑定的元素上时,会通过事件冒泡机制从而触发它的外层元素的绑定事件上,然后在外层元素上去执行函数。

举个例子,比如一个小组的同事点的外卖同时到了,一种方法就是他们一个个下去拿,还有一种方法就是把这件事情委托给组长,让一个人出去拿所有人的外卖,然后再根据收件人一一分发给每个同事;

在这里,拿外卖就是一个事件,每个同事指的是需要响应事件的 DOM 元素,而出去统一领取快递的组长就是代理的元素,所以真正绑定事件的是这个代理元素,按照收件人分发快递的过程就是在事件执行中,需要判断当前响应的事件应该匹配到被代理元素中的哪一个或者哪几个。

  • 委托的优点 1.减少内存消耗

举例,如果我们有一个divdiv之中有大量的button,我们需要在点击button的时候响应一个事件;

<div id="div1">
      <button>click 1</button>
      <button>click 2</button>
      <button>click 3</button>
      .....
      <button>click n</button>
</div>

如果给每个button一一都绑定一个函数,那对于内存消耗是非常大的,效率上需要消耗很多性能;

比较好的方法就是监听这 n 个button的祖先,等冒泡的时候判断target是不是这n个button的一个;

div1.addEventListener('click',(e)=>{
    const t = e.target
    //判断是否匹配目标元素
    if(t.tagName.toLowerCase() === 'button'){
        console.log('button 被点击了')
    }
})

2.监听动态元素

如果你要监听目前不存在的元素的点击事件怎么办

答:监听祖先,等点击的时候看看是不是我要监听的元素即可

举例:

<!--......省略-->
    <div id="div1"></div>
......
//我一秒之后往div里添加一个button
setTimeout(()=>{
    const button = document.createElement('button')
    button.textContent = 'click 1'
    div1.appendChild(button)
},1000)

//这时候我想直接监听button点击事件就不行了,因为它一秒后出现
//所以我只能使用事件委托 通过监听它的祖先,等button出现点击判断即可
div1.addEventListener('click',(e)=>{
    const t = e.target
    if(t.tagName.toLowerCase() === 'button'){
        console.log('button被点击了')
    }
})