手写事件委托

204 阅读1分钟

一、你可能会想到下面这个写法:

ul.addEventListener('click', function(e){

    if(e.target.tagName.toLowerCase() === 'li'){

    fn()// 执行某个函数

    }

})

这样写会有一个bug,如果用户点击的是li里面的span,就没办法触发fn()了

所以我们改成下面这样写:

思路是点击 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

}