事件委托

106 阅读2分钟

事件委托

事件委托就是把原本需要绑定在子元素上的事件(onclick、onkeydown 等)委托给它的父元素,让父元素来监听子元素的冒泡事件,并在子元素发生事件冒泡时找到这个子元素。

举个简单的例子,整个宿舍的同学都需要去取快递,一种方法是让他们一个个去取,另一种方法是把这件事委托给宿舍长,让宿舍长把所有人的快递都取回来,然后再根据收件人一一分发给宿舍的同学。在这里,我们可以将取快递看作一个事件;每个同学看作是需要绑定事件的 DOM 元素;宿舍长看作是这些 DOM 元素的父元素,事件需要绑定在这个父元素上;按照收件人分发快递的过程就是事件执行的过程。

场景1:

要给100个按钮添加点击事件,咋办?

答:监听这个100个按钮的祖先,等冒泡的时候判断target是不是这100个按钮中的一个

代码:

检查按钮点击情况

场景2:

你要监听目前不存在的元素的点击事件?

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

优点:省监听数(内存),可以动态监听元素

代码:

检查1s后生成的按钮的点击情况

封装一个事件委托

只要实行一个函数就可以实现事件委托

要求:

写出这样一个函数on('click','#testDiv','li',fn)

当用户点击#testDiv里面的li元素时,调用fn函数

要求用到事件委托

饥封装事件委托

代码:

setTimeout(()=>{
  const button = document.createElement('button')
  const span = document.createElement('span')
  span.textContent='click 1'
  button.appendChild(span)
  div1.appendChild(button)
},1000)

on('click','#div1','button',()=>{
  console.log('button被点击了')
})



function on(eventType,element, selector, fn) {
  if(!(element instanceof Element)){
    element = document.querySelector(element)
  }  
  element.addEventListener(eventType, e => {
      let el = e.target
      console.log(el)
      while (!el.matches(selector)) {
        if (element === el) {
          el = null
          break
        }
        el = el.parentNode
        console.log(el)
      }
      el && fn.call(el, e, el)
    })
    return element
  }