1. 事件代理_委托
什么事件委托?
事件委托是指目标元素将自身的响应事件委托给其父级元素来响应。
事件委托的工作原理基于浏览器的冒泡机制。
为什么要用事件委托?
在Javascript
中,添加到页面的事件处理程序数量影响页面的整体运行性能。
影响页面性能的因素有:
js
中的一切都是对象,每个对象都占据内存,内存中的对象越多,性能越差。- 如需为特定的每个节点都添加事件监听函数,必然增加
DOM
的访问次数而延迟整个页面的交互时间。
事件委托利用事件冒泡的性质,只指定一个事件处理程序,就可以管理某一类型的所有事件。事件监听器并没有添加在每个节点上,而是添加到它们的父元素上。事件监听器会分析从子元素冒泡上来的事件,并识别出是哪个子元素的事件。大大减少了对DOM
的访问。
假若现在有一个UL
表单,其中的每个列表项都有一个click
事件。
<ul id="parent-list">
<li id="post-1">Item 1</li>
<li id="post-2">Item 2</li>
<li id="post-3">Item 3</li>
<li id="post-4">Item 4</li>
<li id="post-5">Item 5</li>
<li id="post-6">Item 6</li>
</ul>
普通监听器绑定方式
var listArray = document.getElementById('parent-list').childNodes;
for(var i=0;i<listArray.length;i++){
listArray[i].addEventListener('click',function({
alert(this.innerText);
});
}
事件委托实现
// 获取父节点,并为它添加一个click事件
document.getElementById("parent-list").addEventListener("click",function(e) {
// 检查事件源e.targe是否为Li
if(e.target && e.target.nodeName.toUpperCase == "LI") {
// 真正的处理过程在这里
console.log("List item ",e.target.id.replace("post-")," was clicked!");
}
});
这样,只需为UL
设置一个click
事件监听器就可以捕获到事件的来源并执行特定的操作,而无需为每个Li
列表项添加一个监听器。加在列表UL
上的事件监听器也能捕获到其他子元素的click
(特定)事件,在应用时,应加以区别或排除。
事件委托的作用?
除了上面讲到的可以减少对DOM
的访问而提高性能的作用外,事件委托还可以监听动态增加的元素。
对于上面的UL
列表,如果再动态增加一个Li
列表项,对于原始的事件监听绑定方式,点击新增的Li
表项后,不会有任何结果。因为并没有为它绑定事件监听器。而事件委托的方式则不同,因为它是在父元素上绑定了事件监听器,因而父元素的任何子元素都有触发该监听器的能力。
综上,事件委托的优点有如下几点。
管理的函数变少,不需要为每个元素都添加事件监听函数。
可以动态的增加和修改元素,无需因为元素的改动而修改事件绑定。
Javascript
和DOM
节点之间的关联变少,降低了循环引用的导致内存泄漏的可能性。
事件委托的缺点。
如果绑定监听器的父元素和目标元素的层级相距较远,那么在冒泡过程中会消耗一定的时间。