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 相关文章推荐
js弹出层(jQuery插件形式附带reLoad功能)
Apr 12 Javascript
上传的js验证(图片/文件的扩展名)
Apr 25 Javascript
jquery对元素拖动排序示例
Jan 16 Javascript
完美兼容IE,chrome,ff的设为首页、加入收藏及保存到桌面js代码
Dec 17 Javascript
js仿小米官网图片轮播特效
Sep 29 Javascript
jquery广告无缝轮播实例
Jan 05 Javascript
微信小程序 tabs选项卡效果的实现
Jan 05 Javascript
浅谈Angular.js中使用$watch监听模型变化
Jan 10 Javascript
详谈Ajax请求中的async:false/true的作用(ajax 在外部调用问题)
Feb 10 Javascript
解决OneThink中无法异步提交kindeditor文本框中修改后的内容方法
May 05 Javascript
Vue.js中 v-model 指令的修饰符详解
Dec 03 Javascript
vue路由结构可设一层方便动态添加路由操作
Aug 31 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
德生PL660的电路分析和打磨
2021/03/02 无线电
德生PL990,目前市面上唯一一款便携式插卡蓝牙全波段高性能收音机
2021/03/02 无线电
php动态生成函数示例
2014/03/21 PHP
CodeIgniter实现更改view文件夹路径的方法
2014/07/04 PHP
LNMP部署laravel以及xhprof安装使用教程
2017/09/14 PHP
JS 页面内容搜索,类似于 Ctrl+F功能的实现代码
2007/08/13 Javascript
jquery autocomplete自动完成插件的的使用方法
2010/08/07 Javascript
最短的IE判断代码
2011/03/13 Javascript
JS中表单的使用小结
2014/01/11 Javascript
jQuery插件Timelinr 实现时间轴特效
2015/10/04 Javascript
使用JavaScript实现ajax的实例代码
2016/05/11 Javascript
Nodejs中使用captchapng模块生成图片验证码
2017/05/18 NodeJs
php简单数据库操作类的封装
2017/06/08 Javascript
基于Vue2实现简易的省市区县三级联动组件效果
2018/11/05 Javascript
VuePress 快速踩坑小结
2019/02/14 Javascript
详解nodejs http请求相关总结
2019/03/31 NodeJs
ES6 class的应用实例分析
2019/06/27 Javascript
浅谈vue 锚点指令v-anchor的使用
2019/11/13 Javascript
Vue.js实现大屏数字滚动翻转效果
2019/11/29 Javascript
js实现移动端图片滑块验证功能
2020/09/29 Javascript
Python随手笔记之标准类型内建函数
2015/12/02 Python
浅谈Python中range和xrange的区别
2017/12/20 Python
python elasticsearch从创建索引到写入数据的全过程
2019/08/04 Python
python 实现线程之间的通信示例
2020/02/14 Python
Python打包工具PyInstaller的安装与pycharm配置支持PyInstaller详细方法
2020/02/27 Python
Python定义函数实现累计求和操作
2020/05/03 Python
巴西最大的体育用品商城:Netshoes巴西
2016/11/29 全球购物
英国折扣高尔夫商店:Discount Golf Store
2019/11/19 全球购物
旅游管理实习自我鉴定
2013/09/29 职场文书
人口与计划生育目标管理责任书
2014/07/29 职场文书
个人剖析材料范文
2014/09/30 职场文书
初中家长评语大全
2014/12/26 职场文书
2015年学校政教处工作总结
2015/05/26 职场文书
哈姆雷特读书笔记
2015/06/29 职场文书
教师培训学习心得体会
2016/01/21 职场文书
SQLServer权限之只开启创建表权限
2022/04/12 SQL Server