手写事件委托

错误版(但是可能能通过面试)

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

bug 在于,如果用户点击的是 li 里面的 span,就没法触发 fn,这显然不对。

好处

  1. 节省监听器

  2. 实现动态监听

坏处

调试比较复杂,不容易确定监听者。

解决坏处

解决不了

高级版(不用背)

思路是点击 span 后,递归遍历 span 的祖先元素看其中有没有 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 element
}

delete(ul, 'click', 'li', f1)

Last updated