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 相关文章推荐
基于Jquery插件开发之图片放大镜效果(仿淘宝)
Nov 19 Javascript
JavaScript中的比较操作符>、=、
Dec 31 Javascript
跟我学习javascript的prototype原型和原型链
Nov 18 Javascript
Angular表单验证实例详解
Oct 20 Javascript
Easyui Datagrid自定义按钮列(最后面的操作列)
Jul 13 Javascript
详解JS中的柯里化(currying)
Aug 17 Javascript
react的滑动图片验证码组件的示例代码
Feb 27 Javascript
小程序如何支持使用 async/await详解
Sep 12 Javascript
解决vue中的无限循环问题
Jul 27 Javascript
JS删除对象中某一属性案例详解
Sep 08 Javascript
如何手动实现一个 JavaScript 模块执行器
Oct 16 Javascript
js实现弹幕墙效果
Dec 10 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
PHP版自动生成文章摘要
2008/07/23 PHP
php addslashes和mysql_real_escape_string
2010/01/24 PHP
php+ajax无刷新上传图片的实现方法
2016/12/06 PHP
PHP获取文本框、密码域、按钮的值实例代码
2017/04/19 PHP
PDO::_construct讲解
2019/01/27 PHP
超强的IE背景图片闪烁(抖动)的解决办法
2007/09/09 Javascript
JavaScript网页定位详解
2014/01/13 Javascript
Window.Open如何在同一个标签页打开
2014/06/20 Javascript
JS基于Ajax实现的网页Loading效果代码
2015/10/27 Javascript
JavaScript预解析及相关技巧分析
2016/04/21 Javascript
JavaScript遍历Json串浏览器输出的结果不统一问题
2016/11/03 Javascript
Vue 固定头 固定列 点击表头可排序的表格组件
2016/11/25 Javascript
JS实现点击循环切换显示内容的方法
2017/10/19 Javascript
浏览器调试动态js脚本的方法(图解)
2018/01/19 Javascript
Vue中使用better-scroll实现轮播图组件
2020/03/07 Javascript
JavaScript实现简单的弹窗效果
2020/05/19 Javascript
[08:44]DOTA2发布会群星聚首 我们都是刀塔人
2014/03/21 DOTA
[01:14:30]TNC vs VG 2019国际邀请赛淘汰赛 胜者组赛BO3 第二场 8.20.mp4
2019/08/22 DOTA
可用于监控 mysql Master Slave 状态的python代码
2013/02/10 Python
Python字符串和正则表达式中的反斜杠('\')问题详解
2019/09/03 Python
使用PyTorch实现MNIST手写体识别代码
2020/01/18 Python
JavaScript+Canvas实现自定义画板的示例代码
2019/05/13 HTML / CSS
size?德国官方网站:英国伦敦的球鞋精品店
2018/03/17 全球购物
英国女士和男士时尚服装网上购物:Top Labels Online
2018/03/25 全球购物
澳大利亚现代波西米亚风格女装网站:Bohemian Traders
2018/04/16 全球购物
如何掌握自荐信格式呢
2013/11/19 职场文书
就业表自我评价分享
2014/02/06 职场文书
广告词串烧
2014/03/19 职场文书
文体活动实施方案
2014/03/27 职场文书
学生会竞选演讲稿纪检部
2014/08/25 职场文书
客户答谢会活动方案
2014/08/31 职场文书
党建工作汇报材料
2014/12/24 职场文书
毕业论文致谢怎么写
2015/05/14 职场文书
家电创业计划书
2019/08/05 职场文书
SQL Server中搜索特定的对象
2022/05/25 SQL Server
mysql拆分字符串作为查询条件的示例代码
2022/07/07 MySQL