JS之事件代理
事件代理(事件委托)
事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。
有个例子可以帮助理解:
有三个同事预计会在周一收到快递。为了签收快递,有两种办法:一是三个人在公司门口等快递;二是委托给前台MM代为签收。现实当中,我们大都采用委托的方案(公司也不会容忍那么多员工站在门口就为了等快递)。前台MM收到快递后,她会判断收件人是谁,然后按照收件人的要求签收。这种方案还有一个优势,那就是即使公司里来了新员工(不管多少),前台MM也会在收到寄给新员工的快递后核实并代为签收。
这里其实还有2层意思的:
第一,现在委托前台的同事是可以代为签收的,即程序中的现有的DOM节点是有事件的;
第二,新员工也是可以被前台MM代为签收的,即程序中新添加的DOM节点也是有事件的。
事件代理的原理
事件代理是利用事件的冒泡原理来实现的,将子元素的事件利用冒泡原理委托给父元素来实现。
事件代理的目的
一般来说,DOM需要有事件处理程序,我们都会直接给它添加事件处理程序就好了,那如果是很多的DOM需要添加事件处理呢?比如我们有100个li,每个li都有相同的click点击事件,可能我们会遍历所有的li,然后给它们添加事件,那这么做会存在什么影响呢?
在JavaScript中,添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能,因为需要不断的与DOM节点进行交互,访问DOM的次数越多,引起浏览器重绘与回流的次数也就越多,就会延长整个页面的交互就绪时间,如果用事件代理(事件委托),就会将所有的操作放到JS程序里面,与DOM的操作就只需要交互一次,这样就能大大的减少与DOM的交互次数,提高性能。
每个函数都是一个对象,是对象就会占用内存,对象越多,内存占用率就越大,自然性能就越差了,比如上面的100个li,就要占用100个内存空间,如果是1000个,10000个呢?,如果用事件代理(事件委托),那么我们就可以只对它的父级(如果只有一个父级)这一个对象进行操作,这样我们就需要一个内存空间就够了,自然性能就会更好。
事件代理的实现
HTML部分
<div class="nav">
<ul>
<li><a>栏目一</a></li>
<li><a>栏目二</a></li>
<li><a>栏目三</a></li>
<li><a>栏目四</a></li>
</ul>
<div>不是栏目</div>
</div>
JS部分
function $(selector){
return document.querySelector(selector);
}
$(".nav").addEventListener("click",function(e){
if(e.target.nodeName.toLowerCase() == "a"){
console.log(e.target);
}
});