委托模式

作者: 姜治宇 | 来源:发表于2020-04-17 22:19 被阅读0次

    委托模式比较简单,我们先来看个垃圾代码,估计你以前也造过:

    let ul = document.getElementById('cont')//外部容器
    
    let li = document.getElementsByTagName('li')//列表
    
    for(let i=0;i<li.length;i++){
        li[i].onclick = function(){
            this.style.backgroundColor = 'grey'
        }
    }
    

    为啥说这是一摊垃圾呢?
    因为for循环将dom对象绑定了n个事件,这些事件的回调函数本身也是对象,会一下子吃掉好多堆内存空间,对性能来说是个很大的问题。
    如何解决呢?
    很简单,委托父元素。

    let ul = document.getElementById('cont')//外部容器
    
    ul.onclick = function (e) {
        let tar = e.target
        if (tar.nodeName.toLowerCase() === 'li') {
            tar.style.backgroundColor = 'grey'
        }
    }
    

    没错,就是利用利用事件流模型,从事件捕获开始,到触发该事件,然后再到事件冒泡三个阶段,我们可以将子元素的事件委托给更高层面的父元素来绑定执行,这就是体现了委托模式的思想。
    下面再看一段垃圾代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>委托模式</title>
    </head>
    <body>
        <div id="cont">
            <button id="btn">click</button>
        </div>
    </body>
    </html>
    <script>
        var btn = document.querySelector('#btn')
        btn.onclick = function(){
            document.querySelector('#cont').textContent = '替换了按钮'
        }
    </script>
    

    为什么是垃圾呢?
    因为btn按钮被替换掉了,但是对btn绑定的onclick事件并未释放掉,这个回调函数仍然存在于堆内存中,时间久了就会出现内存泄露了。
    我们可以用委托模式改造一下:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>委托模式</title>
    </head>
    <body>
        <div id="cont">
            <button id="btn">click</button>
        </div>
    </body>
    </html>
    <script>
        var cont = document.querySelector('#cont')
    
        cont.onclick = function(e){
    
            if(e.target.id === 'btn'){
                this.textContent = '替换了按钮'
            }
    
        }
    </script>
    

    相关文章

      网友评论

        本文标题:委托模式

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