基本概念
事件委托,通俗地来讲,就是把一个元素响应事件(click、keydown……)的函数委托到另一个元素;
一般来讲,会把一个或者一组元素的事件委托到它的父层或者更外层元素上,真正绑定事件的是外层元素,当事件响应到需要绑定的元素上时,会通过事件冒泡机制从而触发它的外层元素的绑定事件上,然后在外层元素上去执行函数。
举一个例子,比如说你要给100个按钮添加点击事件,该如何做?难道要为每一个按钮都增加一个点击事件吗,太麻烦了。这时我们需要监听这100个按钮的祖先,等冒泡的是判断target是不是这100个按钮中的一个。这样做极大减少了重复程度。
也可以举一下现实生活中的例子取快递:有三个同事预计会在周一收到快递。为签收快递,有两种办法:一是三个人在公司门口等快递;二是委托给前台代为签收。现实当中,我们大都采用委托的方案。前台收到快递后,她会判断收件人是谁,然后按照收件人的要求签收,甚至代为付款。这种方案还有一个优势,那就是即使公司里来了新员工(不管多少),前台也会在收到寄给新员工的快递后核实并代为签收。
为什么要进行事件委托
一般来说,dom需要有事件处理程序,那么我们直接给他设置相应的处理程序就好了,可是比如一个ul里面有好多个li需要每一个都设置点击事件,那么可能我们首先会想到利用for循环实现。代码如下:
<ul>
<li>121221212</li>
<li>121221212</li>
<li>121221212</li>
<li>121221212</li>
<li>121221212</li>
<li>121221212</li>
<li>121221212</li>
<li>121221212</li>
</ul>
let lis=document.getElementsByTagName('li');
for(let i=0;i<lis.length;i++){
lis[i].onclick=function(){
this.style.background='red';
}
}
当点击事件发生后,首先要找到ul,然后遍历li,然后点击li的时候,又要找一次目标li的位置,才能执行最后的操作,每次点击都要找一次li,直到找到当前点击的DOM节点li为止,这样再点击别的li,上面的操作就又循环往复,效果虽然实现了,但是大大的增加的页面的交互量,交互次数越多,浏览器重绘与重排的次数也就越多,就会延长整个页面的交互就绪时间,这样就会很耗费内存的,性能也就会下降了,网站的体验效果就会下降很多,这就是为什么性能优化的主要思想之一就是减少DOM操作的原因。
使用事件委托:
<ul class="aa">
<li>121221212</li>
<li>121221212</li>
<li>121221212</li>
<li>121221212</li>
<li>121221212</li>
<li>121221212</li>
<li>121221212</li>
<li>121221212</li>
</ul>
let a=document.getElementsByClassName('aa')[0];
a.onclick=function(e){
e.target.style.background='red';
}
那么每点击一次就只对它的父级(如果只有一个父级)这一个对象进行操作,与dom的操作就只需要交互一次,这样就能大大的减少与dom的交互次数,这样我们就需要一个内存空间就够了,增加了性能。