jQuery选择器的工作原理和优化分析


Posted in Javascript onJuly 25, 2011

每次申明一个jQuery对象的时候,返回的是jQuery.prototype.init 对象,很多人就会不明白,init明明是jQuery.fn的方法啊,实际上这里不是方法,而是init的构造函数,因为js的prototype对象可 以实现继承,加上js的对象只是引用不会是拷贝,new jQuery,new jQuery.fn和new jQuery.fn.init的子对象是一样的,只是有没有执行到init的不同,这里就不讲原因了,等下一篇再讲为什么会是这样。
当我们使用选择器的时候$(selector,content),就会执行 init(selectot,content),我们看看inti中是怎样执行的:

if ( typeof selector == "string" ) { 
//正则匹配,看是不是HTML代码或者是#id 
var match = quickExpr.exec( selector ); 
//没有作为待查找的 DOM 元素集、文档或 jQuery 对象。 
//selector是#id的形式 
if ( match && (match[1] || !context) ) { 
// HANDLE: $(html) -> $(array) 
//HTML代码,调用clean补全HTML代码 
if ( match[1] ){ 
selector = jQuery.clean( [ match[1] ], context ); 
} 
// 是: $("#id") 
else { 
//判断id的Dom是不是加载完成 
var elem = document.getElementById( match[3] ); 
if ( elem ){ 
if ( elem.id != match[3] ) 
return jQuery().find( selector ); 
return jQuery( elem );//执行完毕return 
} 
selector = []; 
} 
//非id的形式.在context中或者是全文查找 
} else{ 
return jQuery( context ).find( selector ); 
} 
}

这里就说明只有选择器写成$(‘#id')的时候最快,相当于执行了一次 getElementById,后边的程序就不用再执行了。当然往往我们需要的选择器并不是这么简单,比如我们需要id下的CSS为className, 有这样的写法$(‘#id.className')和$(‘#id').find(‘.className');这两种写法的执行结果都是一样的,比 如<div id=”id”><span class=”className”></span></div>,返回的肯定都是<span class=”className”></span>,但是执行的效率是完全不一样的。
在分析一下上边的代码,如果不是$(‘#id')这样的简单选择器的话,都会执行find函 数,那我们再看看find到底是做用的:
find: function( selector ) { 
//在当前的对象中查找 
var elems = jQuery.map(this, function(elem){ 
return jQuery.find( selector, elem ); 
}); 
//下边的代码可以忽略,只是做一些处理 
//这里应用了js的正则对象的静态方法test 
//indexOf("..")需要了解一下xpath的语法,就是判断selector中包含父节点的写法 
//本意就是过滤数组的重复元素 
return this.pushStack( /[^+>] [^+>]/.test( selector ) || selector.indexOf("..") > -1 ? 
jQuery.unique( elems ) : 
elems ); 
}

如果这样写$(‘#id .className'),就会执行到扩展的find(‘#id .className',document),因为当前的this是document的jQuery数组,那我们在看看扩展的find他的实现,代码比较 多,就不列出来,总之就是从第二个参数传递进行的dom第一个子节点开始找,遇见#比对id,遇见.比对ClassName,还有:<+-等处理。 那我们要优化,是不是就要想办法让第二个参数context的范围最小,那样遍历是不是就很少了?
如果我们这样写$(‘#id').find(‘.className'),那程序只这样执行 的,第一次init的时候执行一步getElementById,就return了,接着执行 find(‘.className',divDocument),divDocument就是我们第一次选择的是div标签,如果document下有很 多dom对象的时候,这次只遍历divDocument是不是少了很多次,而且在第一次选择id的速度也要比遍历快的多。
现在大家应该是明白了吧。就是说第一层选择最好是ID,而是简单选择器,目的就是定义范围, 提高速度,这次就说这些,选择写法的优化,其他的优化,下次再说。
Javascript 相关文章推荐
js bind 函数 使用闭包保存执行上下文
Dec 26 Javascript
js替代copy(示例代码)
Nov 27 Javascript
JS函数this的用法实例分析
Feb 05 Javascript
jquery插件tytabs.jquery.min.js实现渐变TAB选项卡效果
Aug 25 Javascript
基于Angularjs实现分页功能
May 30 Javascript
jQuery解析XML 详解及方法总结
Sep 28 Javascript
javascript中获取元素标签中间的内容的实现方法
Oct 08 Javascript
JS实现的五级联动菜单效果完整实例
Feb 23 Javascript
jQuery使用unlock.js插件实现滑动解锁
Apr 04 jQuery
基于javascript的拖拽类封装详解
Apr 19 Javascript
解决vue与node模版引擎的渲染标记{{}}(双花括号)冲突问题
Sep 11 Javascript
详解vue中使用transition和animation的实例代码
Dec 12 Vue.js
Jquery 点击按钮显示和隐藏层的代码
Jul 25 #Javascript
multiSteps 基于Jquery的多步骤滑动切换插件
Jul 22 #Javascript
JavaScript实现页面滚动图片加载(仿lazyload效果)
Jul 22 #Javascript
JS 自定义带默认值的函数
Jul 21 #Javascript
表单切换,用回车键替换Tab健(不支持IE)
Jul 20 #Javascript
在浏览器中获取当前执行的脚本文件名的代码
Jul 19 #Javascript
iframe 异步加载技术及性能分析
Jul 19 #Javascript
You might like
php in_array 函数使用说明与in_array需要注意的地方说明
2010/04/13 PHP
php+mysql查询优化简单实例
2015/01/13 PHP
php 5.6版本中编写一个PHP扩展的简单示例
2015/01/20 PHP
在CentOS上搭建LAMP+vsftpd环境的简单指南
2015/08/01 PHP
PHP中key和current,next的联合运用实例分析
2016/03/29 PHP
PHP自动补全表单的两种方法
2017/03/06 PHP
PHP操作MySQL中BLOB字段的方法示例【存储文本与图片】
2017/09/15 PHP
页面只能打开一次Cooike如何实现
2012/12/04 Javascript
通用javascript代码判断版本号是否在版本范围之间
2015/11/29 Javascript
jquery实现简单文字提示效果
2015/12/02 Javascript
JavaScript中输出信息的方法(信息确认框-提示输入框-文档流输出)
2016/06/12 Javascript
ES6记录异步函数的执行时间详解
2016/08/31 Javascript
Bootstrap按钮功能之查询按钮和重置按钮
2016/10/26 Javascript
Javascript 正则表达式校验数字的简单实例
2016/11/02 Javascript
基于JS实现限时抢购倒计时间表代码
2017/05/09 Javascript
nodejs一个简单的文件服务器的创建方法
2019/09/13 NodeJs
Vue如何循环提取对象数组中的值
2020/11/18 Vue.js
详解Python中的条件判断语句
2015/05/14 Python
简单讲解Python中的数字类型及基本的数学计算
2016/03/11 Python
Python求出0~100以内的所有素数
2018/01/23 Python
django如何通过类视图使用装饰器
2019/07/24 Python
基于python实现百度语音识别和图灵对话
2020/11/02 Python
paramiko使用tail实时获取服务器的日志输出详解
2020/12/06 Python
pytorch下的unsqueeze和squeeze的用法说明
2021/02/06 Python
非凡女性奢华谦虚风格:The Modist
2017/10/28 全球购物
思想政治自我鉴定
2013/10/06 职场文书
转预备党员政审材料
2014/02/06 职场文书
校运会入场式解说词
2014/02/10 职场文书
实习单位鉴定评语
2014/04/26 职场文书
浪漫婚礼主题活动策划方案
2014/09/15 职场文书
民主评议党员自我评价材料
2014/09/18 职场文书
警察群众路线对照检查材料思想汇报
2014/10/01 职场文书
结婚当天新郎保证书
2015/05/08 职场文书
幼儿园国培研修日志
2015/11/13 职场文书
创业计划书之川味火锅店
2019/09/02 职场文书
java如何实现socket连接方法封装
2021/09/25 Java/Android