加载中…
正文 字体大小:

JavaScript事件委托优化

(2011-06-01 16:38:00)
标签:

事件处理函数

监听

元素

委托

页面

it

分类: jquery

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

阅读 评论 收藏 转载 喜欢 打印举报
已投稿到:
  • 评论加载中,请稍候...
发评论

       

    发评论

    以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

      

    新浪BLOG意见反馈留言板 不良信息反馈 电话:4006900000 提示音后按1键(按当地市话标准计费) 欢迎批评指正

    新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 会员注册 | 产品答疑

    新浪公司 版权所有