事件委托的原理
事件委托(委派)是利用JavaScript的事件冒泡机制,指定一个事件处理程序,就可以管理某一类型的所有事件。
通俗的来讲(此处引用前端大牛的例子),就是:
有三个同事预计会在周一收到快递。为签收快递,有两种办法:一是三个人在公司门口等快递;二是委托给前台
MM代为签收。现实当中,我们大都采用委托的方案(公司也不会容忍那么多员工站在门口就为了等快递)。前台MM收
到快递后,她会判断收件人是谁,然后按照收件人的要求签收,甚至代为付款。这种方案还有一个优势,那就是即使
公司里来了新员工(不管多少),前台MM也会在收到寄给新员工的快递后核实并代为签收。
这里其实还有2层意思的:
第一,现在委托前台的同事是可以代为签收的,即程序中的现有的dom节点是有事件的;
第二,新员工也是可以被前台MM代为签收的,即程序中新添加的dom节点也是有事件的。
事件委托(代理)的优缺点
在JavaScript中,添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能,因为需要不断的与dom节点进行交互,访问dom的次数越多,引起浏览器重绘与重排的次数也就越多,就会延长整个页面的交互就绪时间,这就是为什么性能优化的主要思想之一就是减少DOM操作的原因;如果要用事件委托,就会将所有的操作放到js程序里面,与dom的操作就只需要交互一次,这样就能大大的减少与dom的交互次数,提高性能;
每个函数都是一个对象,是对象就会占用内存,对象越多,内存占用率就越大,自然性能就越差了(内存不够用,是硬伤,哈哈),比如上面的100个li,就要占用100个内存空间,如果是1000个,10000个呢,那只能说呵呵了,如果用事件委托,那么我们就可以只对它的父级(如果只有一个父级)这一个对象进行操作,这样我们就需要一个内存空间就够了,是不是省了很多,自然性能就会更好。
优点
1.可以大量节省内存占用,减少事件注册。比如ul上代理所有li的click事件就很不错。
2.可以实现当新增子对象时,无需再对其进行事件绑定,对于动态内容部分尤为合适
缺点
事件代理的常用应用应该仅限于上述需求,如果把所有事件都用事件代理,可能会出现事件误判。即本不该被触发的事件被绑定上了事件。
事件委托的实现
dom结构
<ul class="lis">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
原生js中实现
window.addEventListener('load',function(){
//获取元素
var lis = document.querySelector('.lis');
//监听点击事件
lis.addEventListener('click',function(e){
var ev = ev || window.event;//ie兼容性
var target = ev.target || ev.srcElement;//ie兼容性
//判断事件源是否是li
if(target.nodeName.toLowerCase() == 'li'){
alert('1111');
}
})
})
jQuery中实现
//事件处理element.on()
$('.lis').on('click','li',function(){
$(this).css('backgroundColor','pink').siblings().css('backgroundColor','#fff');
alert(11111);
});
总结
上面是用事件委托的方式,新添加的子元素背景是带有事件效果的,我们可以发现,当用事件委托的时候,根本就不需要去遍历元素的子节点,只需要给父级元素添加事件就好了,其他的都是在js里面的执行,这样可以大大的减少dom操作,这才是事件委托的精髓所在。
适合用事件委托的事件:click,mousedown,mouseup,keydown,keyup,keypress。