js事件委托

作者: 饥人谷_oathy | 来源:发表于2017-04-24 23:40 被阅读52次

    我们收取快递有两种方法:一是在特定的地点等快递的到来,二是委托人代收。现实当中,我们大都采用委托的方案。而委托人接受的委托不止一份,他会判断收件人,从而发放到各自手中。这也就是js事件委托的通俗理解。

    为啥要用事件委托?

    一般来说,dom需要有事件处理程序,我们都会直接给它设事件处理程序就好了,那为什么要用事件委托呢?
    独立典型的程序或许需要单独的处理程序,但是程序的结构越复杂庞大,就会有大量重复的程序事件。单独直接得处理程序,会严重影响工作的效率。可能,我们能用for循环等方法,遍历所以程序,但这会导致与dom节点的不断交互,访问dom的次数越多,引起浏览器重绘与重排的次数也就越多,就会延长整个页面的交互就绪时间,这就是为什么性能优化的主要思想之一就是减少DOM操作的原因。
    所以如果要用事件委托,就会将所有的操作放到js程序里面,与dom的操作就只需要交互一次,这样就能大大的减少与dom的交互次数,提高性能

    如何实现事件委托?

    事件委托是利用事件的冒泡原理来实现的事件从最深的节点开始,然后逐步向上传播至最上层的事件。

    网上常见的例子

     <ul id="ul">
            <li>1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
        </ul>
    

    我们需要把li的点击事件绑定到ul上

    var ul = document.getElementById('ul')
    ul.addEventListener('click', function() {})
    

    这样我们就实现了委托,但是有出现了新的问题,如果ul内不止li,那么处于ul内的其他元素被点击时,事件也被触发了!
    所以我们需要在触发事件前来一个判断

    ul.addEventListener('click', function(e) 
               // 检查事件源e.targe是否为Li
               if (e.target && e.target.nodeName.toUpperCase == "LI") {
    
                // 真正的处理过程在这里
                console.log("点击成功")
              }
           }
    

    这样就大功告成了?很遗憾,这种情况还存在一个严重的bug,如果元素在li中呢?那么事件就不会触发!比如这样

    <ul id="ul">
        <li id="l1"><span>1</span></li>
        <li id="l2">2</li>
        <li id="l3">3</li>
        <li id="l4">4</li>
    </ul>
    

    那么该怎么做呢?我们需要再加一个判断,判断点击的元素的父辈元素中有没有li,如果有,就继续执行事件。

    ul.addEventListener('click', function() {
                        let el = e.target
                        while (el && !el.matches(selector)) {
                            el = el.parentNode
                            if (element === el) {
                                el = null
                            }
                        }
                        if (el) {
                            console.log('执行回调函数')
                        }
                    }
    

    后记

    我们发现问题,然后找出方法解决问题。并不代表事件的结束,我们所用的方法也许会带来其他的原题。多思考,多测试,不断完善。记住,现在得到的永远不是最佳答案。

    相关文章

      网友评论

        本文标题:js事件委托

        本文链接:https://www.haomeiwen.com/subject/qnrmzttx.html