手写事件委托

139 阅读1分钟

简易版(有bug)

ul.addEventListener('click', function(e){
  // e.target or e.currentTarget
  if(e.target.tagName.toLowerCase() === 'li'){
    fn() // 执行某个函数
  }
})

bug:如果用户点击的是 li 中的 span ,就不能触发 fn 。这显然是不对的。

高级版

思路:点击 span 后,递归遍历 span 的 parent 看其中有没有 ul 里的 li。

function delegate(element, eventType, selector, fn){
  element.addEventListener(eventType, e =>{
    let el = e.target
    while (!el.matches(selector)){
      if(element === el){
        el = null
        break
      }
      el = el.parentNode
    }
    el && fn.call(el, e, el)
  })
  return elemen
}