javascript事件委托

一、什么是事件委托?

    简单的来说,事件委托就是利用js事件冒泡的特性,将内层元素的事件委托给外层处理,网上有个例子描述得特别到位:一个公司有很多个员工,每天都会有快递,如果快递到的时候每个要收快递的员工都去公司门口收,那门口就被堵住了,就算没被堵住,这样的操作效率也不高,所以有人就想,为什么不把快递委托给前台收呢?? 这样就可以不用每个人在上班时间都跑出来收了,节约了人力和时间成本,前台收到了快递再根据快递上的信息找到每个员工就行了,就算有新员工来,前台也照样可以根据信息找到他,这样也免去了新员工因为不熟悉环境而收不到快递的情况,简直一举多得。

二、事件委托js写法和普通写法的对比。

这里我们假设一个需求,页面上有一个无序列表,我们需要每次点击列表中的某一行就在后台打印某一行的内容,需求很简单,我们先看看普通写法怎么实现。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <ul>
        <li id="one">我是1号</li>
        <li id="two">我是2号</li>
        <li id="three">我是3号</li>
        <li id="four">我是4号</li>
    </ul>
    <button id="btn">添加</button>
</body>
<script>
let oUl=document.getElementsByTagName("ul")[0];
let oLi=document.getElementsByTagName("li");
for(let i=0;i<oLi.length;i++){            //遍历元素给每个元素添加点击事件
    oLi[i].onclick=function(){
        console.log(oLi[i].innerText);
    }
}
let btn=document.getElementById("btn");
btn.onclick=function(){                    //给按钮添加点击事件
    let aLi=document.createElement("li");     //创建新的li
    aLi.innerHTML=`我是${oLi.length+1}号`;
    aLi.onclick=function(){               //为新节点单独添加事件
        console.log(aLi.innerText);
    };
    oUl.appendChild(aLi);  
};

</script>

</html> 
从上面的代码我们可以看到,用for循环给相应的li添加点击事件,每添加一个就多一次dom操作,加上按钮点击总共五次,而且,在添加新的li元素时,我们还得为新添加元素添加点击事件,这无疑有些繁琐,而且dom操作的次数是没有做优化的,显然当我们页面的li元素很多的时候,性能将会受到严重的影响。
下面我们再看看事件委托的写法:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <ul>
        <li id="one">我是1号</li>
        <li id="two">我是2号</li>
        <li id="three">我是3号</li>
        <li id="four">我是4号</li>
    </ul>
    <button id="btn">添加</button>
</body>
<script>
    let oUl=document.getElementsByTagName("ul")[0];
    let oLi=document.getElementsByTagName("li");
    oUl.onclick=function(ev){           //直接为ul添加点击事件
        ev=ev||window.event;            //ev对象的兼容处理
        let target=ev.target||ev.srcElement;   //通过ev对象的target找到触发事件的元素           
        if(target.nodeName.toLowerCase()=="li"){  //需求中的操作
        console.log(target.innerText);
        }
    };
    let btn=document.getElementById("btn");
    btn.onclick=function(ev){               //为按钮添加点击事件
        let aLi=document.createElement("li");    //新建li元素
        aLi.innerHTML=`我是${oLi.length+1}号`;
        oUl.appendChild(aLi);    //直接将新元素放进ul
    };
    </script>
</html> 
将上面的代码和普通写法进行比对,显然用事件委托的写法更加的简洁,不仅能减少代码量,同时还能减少dom操作次数,实现对性能的优化,简直一举多得。

三、效果展示

页面的效果在性能方面还是差别不大(因为dom操作次数少),

依次点击:
单击按钮添加:
依次点击:

四、小结

经过一系列的实践,我么们总结出事件委托的以下两点:

1.提高性能:每一个函数都会占用内存空间,只需添加一个事件处理程序代理所有事件,所占用的内存空间更少。

2.动态监听:使用事件委托可以自动绑定动态添加的元素,即新增的节点不需要主动添加也可以一样具有和其他元素一样的事件。


作者:一杠
链接:https://juejin.cn/post/6844903984486940679
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
全部评论

相关推荐

评论
点赞
收藏
分享
牛客网
牛客企业服务