jQuery代码优化 遍历篇


Posted in Javascript onNovember 01, 2011

了解了jQuery对DOM进行遍历背后的工作机制,可以在编写代码时有意识地避免一些不必要的重复操作,从而提升代码的性能。本文就从jQuery的遍历机制入手简单探讨一下优化jQuery代码的问题。

jQuery对象栈

jQuery内部维护着一个jQuery对象栈。每个遍历方法都会找到一组新元素(一个jQuery对象),然后jQuery会把这组元素推入到栈中。而每个jQuery对象都有三个属性:context、selector和prevObject,其中的prevObject属性就指向这个对象栈中的前一个对象,而通过这个属性可以回溯到最初的DOM元素集。

jQuery为我们操作这个内部对象栈提供了两个非常有用的方法:

.end()
.andSelf()
调用第一个方法只是简单地弹出一个对象(结果就是回到前一个jQuery对象)。第二个方法更有意思,调用它会在栈中回溯一个位置,然后把两个位置上的元素集组合起来,并把这个新的、组合之后的元素集推入栈的上方。

利用这个DOM元素栈可以减少重复的查询和遍历的操作,而减少重复操作也正是优化jQuery代码性能的关键所在。

优化示例
下面是一个函数(省略了前后代码),用于实现表格行条纹效果:

function stripe() { 
$('#news').find('tr.alt').removeClass('alt'); 
$('#news tbody').each(function() { 
$(this).children(':visible').has('td') 
.filter(':group(3)').addClass('alt'); 
}); 
}

stripe()函数两次使用了ID选择符#news查找元素:一次是为了从带有alt类的行中删除该类,另一次是为了给新选中的行添加这个类。

优化这个函数的方法有两个,一是连缀。

连缀
连缀优化利用的就是jQuery的内部对象栈和.end()方法。优化后的代码如下:

function stripe() { 
$('#news'). 
find('tr.alt').removeClass('alt').end() 
find('tbody').each(function() { 
$(this).children(':visible').has('td') 
.filter(':group(3)').addClass('alt'); 
}); 
}

第一次调用.find()会把表格行推到栈上,然后的.end()方法则把这些行弹出,从而让下一次调用.find()仍然是在#news表格上执行操作。这样就把两次选择符查找减少为一次。

另一个优化方法是缓存。

缓存
所谓缓存,在这里就是把之前操作的结果保存起来,以便将来重用。优化后的代码如下:

var $news = $('#news'); 
function stripe() { 
$news.find('tr.alt').removeClass('alt'); 
$news.find('tbody').each(function() { 
$(this).children(':visible').has('td') 
.filter(':group(3)').addClass('alt'); 
}); 
}

与连缀的方法相比,缓存方式稍嫌冗长,因为额外创建了一个用于保存jQuery对象的变量。但从另一个角度来看,这种方式在代码中可以实现对选中元素的两次操作完全分离,而这也许可以满足我们其他情况下的需求。同样,因为可以把选中的元素保存在stripe()函数之外,也就避免了每次调用函数时重复查询选择符的操作。

结论
利用jQuery的内部对象栈和缓存,可以减少重复的DOM查询及遍历,从而提高脚本执行速度。

因为根据ID在页面中选择元素速度极快,以上两个例子在优化前后不会有明显的性能差异。在实际编码中,应该选择可读性最好、最容易维护的方式。如果真的遇到了性能瓶颈,以上优化技术都可以起到立竿见影的效果。

(注:本文基于《jQuery基础教程(第3版)》相关章节内容编撰而成。)

Javascript 相关文章推荐
Gird事件机制初级读本
Mar 10 Javascript
网络图片延迟加载实现代码 超越jquery控件
Mar 27 Javascript
40款非常棒的jQuery 插件和制作教程(系列一)
Oct 26 Javascript
Node.js中的模块机制学习笔记
Nov 04 Javascript
不到30行JS代码实现Excel表格的方法
Nov 15 Javascript
jQuery中prepend()方法用法实例
Dec 25 Javascript
jquery增加和删除元素的方法
Jan 14 Javascript
在HTML中插入JavaScript代码的示例
Jun 03 Javascript
在小程序Canvas中使用measureText的方法示例
Oct 19 Javascript
使用JavaScript解析URL的方法示例
Mar 01 Javascript
Jquery异步上传文件代码实例
Nov 13 jQuery
vue 使用原生组件上传图片的实例
Sep 08 Javascript
jQuery代码优化 选择符篇
Nov 01 #Javascript
jQuery代码优化之基本事件
Nov 01 #Javascript
js下获得客户端操作系统的函数代码(1:vista,2:windows7,3:2000,4:xp,5:2003,6:2008)
Oct 31 #Javascript
线路分流自动智能跳转代码,自动选择最快镜像网站(js)
Oct 31 #Javascript
IE与Firefox在JavaScript上的7个不同句法分享
Oct 30 #Javascript
加载 Javascript 最佳实践
Oct 30 #Javascript
js判断是否为数组的函数: isArray()
Oct 30 #Javascript
You might like
经典的PHPer为什么被认为是草根?
2007/04/02 PHP
php打开文件fopen函数的使用说明
2013/07/05 PHP
php简单实现MVC
2015/02/05 PHP
WordPress中邮件的一些修改和自定义技巧
2015/12/15 PHP
使用PHP下载CSS文件中的所有图片【几行代码即可实现】
2016/12/14 PHP
javascript管中窥豹 形参与实参浅析
2011/12/17 Javascript
Js如何判断客户端是PC还是手持设备简单分析
2012/11/22 Javascript
关于jQuery中.attr()和.prop()的问题探讨
2013/09/06 Javascript
2014 年最热门的21款JavaScript框架推荐
2014/12/25 Javascript
js表头排序实现方法
2015/01/16 Javascript
jQuery实现Flash效果上下翻动的中英文导航菜单代码
2015/09/22 Javascript
jQuery往返城市和日期查询实例讲解
2015/10/09 Javascript
javascript事件冒泡简单示例
2016/06/20 Javascript
js检测离开或刷新页面时表单数据是否更改的方法
2016/08/02 Javascript
详解微信小程序 登录获取unionid
2017/06/27 Javascript
js+SVG实现动态时钟效果
2018/07/14 Javascript
微信小程序网络请求封装示例
2018/07/24 Javascript
详解Vue底部导航栏组件
2019/05/02 Javascript
[04:49]2014DOTA2国际邀请赛 Newbee顺利挺进总决赛 ImbaTV独家专访
2014/07/19 DOTA
[56:48]FNATIC vs EG 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/16 DOTA
python if not in 多条件判断代码
2016/09/21 Python
Python3.5文件修改操作实例分析
2019/05/01 Python
Python面向对象程序设计之私有变量,私有方法原理与用法分析
2020/03/23 Python
用css3写出气球样式的示例代码
2017/09/11 HTML / CSS
canvas绘制视频封面的方法
2018/02/05 HTML / CSS
美国生日蛋糕店:Bake Me A Wish!
2017/02/08 全球购物
美国眼镜网站:LensCrafters
2020/01/19 全球购物
医学护理系毕业生求职信
2013/10/01 职场文书
外语专业毕业生自我评价分享
2013/10/05 职场文书
经销商培训邀请函
2014/01/21 职场文书
八一建军节部队活动方案
2014/02/04 职场文书
幼儿园中班教学反思
2014/02/10 职场文书
中式结婚主持词
2014/03/14 职场文书
教师节班会主持词
2015/07/06 职场文书
2016银行招聘自荐信
2016/01/28 职场文书
MySQL系列之十 MySQL事务隔离实现并发控制
2021/07/02 MySQL