DOM 的各种事件为丰富的交互提供了可能,在现在的 web 应用程序中,事件处理程序越来越多,越来越复杂,页面中随处可见的事件监听已经司空见惯,但这引出了一个性能的问题,事件监听得越多,页面运行性能就越差。主要原因来自两个方面:1. 每添加一个事件监听,载入页面时都会增加一次对被监听节点的访问,这无疑增加了页面完全准备就绪所需的时间;2. 每一个事件监听函数都会占用内存,而 JavaScript 并不具备分配内存的权利,有限的内存如果被事件监听函数占用得越多,页面性能下降得也越多。
假如有下面的一个无序列表,需要在每一个 li 被点击之后添加或移除一个名为 'active' 的 class 用以标记该项为红色或还原。
<ul id="list"> <li>list 1</li> <li>list 2</li> <li>list 3</li> <li>list 4</li> <li>list 5</li> </ul>
传统监听方法:
$('#list li').click(function(){
$(this).toggleClass('active');
});
在上面的代码中通过 jQuery 的选择器,找到了这个无序列表中的每一个 li 元素,并为其绑定了 click 事件,代码看上去很简单,但实际上 $('#list li') 返回了一个数组,在这个数组中包含了 5 个上面的 li 元素,然后通过迭代为这 5 个元素分别绑定了一个事件处理函数,这意味着当这段 JavaScript 代码被执行过后,内存中多了 5 个对象。
使用事件委托:
事件委托的原理是事件冒泡,这个过程大致如下图所示:
图中右边部分 (Bubbling Phase) 即为事件冒泡的过程,当元素的一个事件被触发后,这个事件会像冒泡一样一直向上(父元素)传递,直到 document ( Firefox ,Chrome ,Safari 冒泡到 window),事件委托的核心就是监听一个 DOM 中更高层、更不具体的元素,等到事件冒泡到这个不具体元素时,通过 event 对象的 target 属性来获取触发事件的具体元素。下面的代码使用了事件委托的方法改进了这个事件处理函数。
$('#nav').click(function(event){
var target = event.target;
$(target).toggleClass('active');
});
在这里,被监听的元素变成了 ul,即刚才所说的不具体的元素。由于事件的冒泡,在每一个 li 上的 click,都会触发 ul 的事件监听,然后通过 event 中的 target 这个指向事件目标(具体元素)的属性获取到被点击到的那个 li ,最后切换 class 'active' 的有无,任务完成。
通过使用事件委托这个技巧,达到相同的目标只监听了一个元素的事件,同样也只添加了 1 个事件处理函数。浏览器为添加事件所要查找并引用的 DOM 更少,由于监听函数变少,内存的使用也同时减少了。如果页面上需要添加事件的元素很多,事件委托对于页面性能改善的作用是不可小视的。
转载于:https://blog.51cto.com/hoogle/717840