Skip to main content

手写事件委托

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

思路:e.target.tagName.toLowerCase === 'li'

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

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

好处:

  • 节省监听器
  • 实现动态监听

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

解决坏处:解决不了

高级版

点击 span 后,递归遍历 span 的祖先元素看其中有没有 ul 里面的 li。

思路:

  1. 声明出发函数 fn
  2. 监听 ul 点击事件
  3. while 循环
    • 终止条件 !el.matches('li')
    • el = el.parentNode
  4. 调用函数指定参数 el && fn.call(el,e,el)
function fn() {console.log('点击出发')}

ul.addEventListener('click',e=>{
let el = e.target
if(ul === el)return

// 向上递归
while (!el.matches('li')) {
el = el.parentNode
}

el && fn.call(el,e,el) // el:this e:目标 el:元素
}) // 默认为 false