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 相关文章推荐
精选的10款用于构建良好易用性网站的jQuery插件
Jan 23 Javascript
可选择和输入的下拉列表框示例
Nov 05 Javascript
js中键盘事件实例简析
Jan 10 Javascript
jQuery获得document和window对象宽度和高度的方法
Mar 25 Javascript
总结jQuery插件开发中的一些要点
May 16 Javascript
js创建数组的简单方法
Jul 27 Javascript
Angular2学习笔记——详解路由器模型(Router)
Dec 02 Javascript
js实现功能比较全面的全选和多选
Mar 02 Javascript
利用PM2部署node.js项目的方法教程
May 10 Javascript
JS中getElementsByClassName与classList兼容性问题解决方案分析
Aug 07 Javascript
JS实现滑动拼图验证功能完整示例
Mar 29 Javascript
Ajax 的初步实现(使用vscode+node.js+express框架)
Jun 18 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/09/10 PHP
php in_array 函数使用说明与in_array需要注意的地方说明
2010/04/13 PHP
php设计模式之组合模式实例详解【星际争霸游戏案例】
2020/03/27 PHP
JS日历 推荐
2006/12/03 Javascript
javascript实现动态增加删除表格行(兼容IE/FF)
2007/04/02 Javascript
jQuery筛选器children()案例详解(图文)
2013/02/17 Javascript
iframe子页面获取父页面元素的方法
2013/11/05 Javascript
基于jquery实现的文字向上跑动类似跑马灯的效果
2014/06/17 Javascript
sails框架的学习指南
2014/12/22 Javascript
javascript+canvas制作九宫格小程序
2014/12/28 Javascript
Javascript中使用A标签获取当前目录的绝对路径方法
2015/03/02 Javascript
javascript实现日期按月份加减
2015/05/15 Javascript
javascript 用函数实现继承详解
2016/05/28 Javascript
jQuery滚动新闻实现代码
2016/06/26 Javascript
微信小程序 解析网页内容详解及实例
2017/02/22 Javascript
微信小程序 slider的简单实例
2017/04/19 Javascript
Angular 4依赖注入学习教程之简介(一)
2017/06/04 Javascript
vue实现axios图片上传功能
2019/08/20 Javascript
JS数组进阶示例【数组的几种函数用法】
2020/01/16 Javascript
适用于 Vue 的播放器组件Vue-Video-Player操作
2020/11/16 Javascript
[42:52]Optic vs Serenity 2018国际邀请赛淘汰赛BO3 第二场 8.22
2018/08/23 DOTA
深入探究Python中变量的拷贝和作用域问题
2015/05/05 Python
python3 pillow生成简单验证码图片的示例
2017/09/19 Python
python中字符串比较使用is、==和cmp()总结
2018/03/18 Python
程序员写Python时的5个坏习惯,你有几条?
2018/11/26 Python
Python面向对象总结及类与正则表达式详解
2019/04/18 Python
Python %r和%s区别代码实例解析
2020/04/03 Python
Python实现多线程下载脚本的示例代码
2020/04/03 Python
设计师家具购买和委托在线市场:Viyet
2016/11/16 全球购物
Sport-Thieme荷兰:购买体育用品
2019/08/25 全球购物
opencv实现图像几何变换
2021/03/24 Python
新学期红领巾广播稿
2014/01/14 职场文书
九年级家长会邀请函
2014/01/15 职场文书
团结主题班会
2015/08/13 职场文书
MySQL基础(二)
2021/04/05 MySQL
Spring Data JPA的Audit功能审计数据库的变更
2021/06/26 Java/Android