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代码优化技巧之通俗版(减少js体积)
Dec 23 Javascript
JavaScript单元测试ABC
Apr 12 Javascript
让人印象深刻的10个jQuery手风琴效果应用
May 08 Javascript
jQuery实现在最后一个元素之前插入新元素的方法
Jul 18 Javascript
根据输入邮箱号跳转到相应登录地址的解决方法
Dec 13 Javascript
vue使用axios跨域请求数据问题详解
Oct 18 Javascript
js实现简单选项卡功能
Mar 23 Javascript
vue服务端渲染添加缓存的方法
Sep 18 Javascript
vue-cli 3.x配置跨域代理的实现方法
Apr 12 Javascript
简单了解前端渐进式框架VUE
Jul 20 Javascript
详解微信小程序入门从这里出发(登录注册、开发工具、文件及结构介绍)
Jul 21 Javascript
js数组的基本使用总结
Jan 18 Javascript
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模板引擎SMARTY
2006/10/09 PHP
PHP数组函数array_multisort()用法实例分析
2016/04/02 PHP
Yii2中关联查询简单用法示例
2016/08/10 PHP
php的4种常用运行方式详解
2016/12/22 PHP
如何判断php mysqli扩展类是否开启
2016/12/24 PHP
PHP curl 或 file_get_contents 获取需要授权页面的方法
2017/05/05 PHP
IOS 开发之NSDictionary转换成JSON字符串
2017/08/14 PHP
jQuery 插件 将this下的div轮番显示
2009/04/09 Javascript
jquery中通过过滤器获取表单元素的实现代码
2011/07/05 Javascript
JavaScript结合AJAX_stream实现流式显示
2015/01/08 Javascript
实现非常简单的js双向数据绑定
2015/11/06 Javascript
BootStrap中Datetimepicker和uploadify插件应用实例小结
2016/05/26 Javascript
JS实现购物车特效
2017/02/02 Javascript
javascript 判断当前浏览器版本并判断ie版本
2017/02/17 Javascript
AngularJS使用拦截器实现的loading功能完整实例
2017/05/17 Javascript
基于Bootstrap分页的实例讲解(必看篇)
2017/07/04 Javascript
vue 自定义组件 v-model双向绑定、 父子组件同步通信的多种写法
2017/11/27 Javascript
常用的 JS 排序算法 整理版
2018/04/05 Javascript
Vue使用高德地图搭建实时公交应用功能(地图 + 附近站点+线路详情 + 输入提示+换乘详情)
2018/05/16 Javascript
详解Vue+ElementUI从零开始搭建自己的网站(一、环境搭建)
2019/04/30 Javascript
javascript实现导航栏分页效果
2019/06/27 Javascript
解决vue单页面修改样式无法覆盖问题
2019/08/05 Javascript
Vue+Node实现商品列表的分页、排序、筛选,添加购物车功能详解
2019/12/07 Javascript
JS寄快递地址智能解析的实现代码
2020/07/16 Javascript
[00:14]护身甲盾
2019/03/06 DOTA
Python处理json字符串转化为字典的简单实现
2016/07/07 Python
Python3实现发送QQ邮件功能(html)
2017/12/15 Python
python 顺时针打印矩阵的超简洁代码
2018/11/14 Python
Python在图片中插入大量文字并且自动换行
2019/01/02 Python
Python numpy数组转置与轴变换
2019/11/15 Python
Python高级特性——详解多维数组切片(Slice)
2019/11/26 Python
美国新兴城市生活方式零售商:VILLA
2017/12/06 全球购物
采购主管的岗位职责
2013/12/17 职场文书
企业诚信承诺书
2014/05/23 职场文书
会员卡清退活动总结
2014/08/27 职场文书
人民检察院起诉书
2015/05/20 职场文书