分享

JavaScript 性能优化技巧:事件委托

 一个人的library 2010-12-27

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 个对象。

使用事件委托:

事件委托的原理是事件冒泡,这个过程大致如下图所示:

DOM事件流

图中右边部分 (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 更少,由于监听函数变少,内存的使用也同时减少了。如果页面上需要添加事件的元素很多,事件委托对于页面性能改善的作用是不可小视的。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多