web前端

委托模式

2020-04-17  本文已影响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>
上一篇 下一篇

猜你喜欢

热点阅读