jquery 选择器引擎sizzle浅析


Posted in Javascript onFebruary 06, 2013

I'm sorry!我用jquery的大概有一年了,只知道$(selector),其内部选择器的流程走向完全不清晰!于是看了jquery的源码,jquery用的选择器的引擎是sizzle,是jquery的作者另一开源项目,在github上面有,号称最快的dom选择器!不到2000行代码。

上面说了不是很精彩的开场白,我么来个 for example: $('.test') 在jquery的流程是怎么走的呢?
1.首先会做如下的判断

/** 
*关于 querySelectorAll函数 
*返回当前文档中匹配一个特定选择器的所有的元素 
*var nodelist = element.querySelectorAll("div.test"); 
*支持浏览器 ie8+,Chrome,Firefox(3.5) 
* 如果你不清楚可以google 一下 
*/ 
if ( document.querySelectorAll ) { 
(function(){ 
var oldSizzle = Sizzle, 
div = document.createElement("div"), 
id = "__sizzle__"; 
div.innerHTML = "<p class='TEST'></p>"; 
// Safari can't handle uppercase or unicode characters when 
// in quirks mode. 
if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) { 
return; 
} 
Sizzle = function( query, context, extra, seed ) { 
//使用querySelectorAll 来查询 
} 
}

如果你的浏览器是ie8+ 或者 谷歌,直接通过内置的querySelectorAll(".test")返回dom结构。 如果你使用是ie6,那么下面事情发生了
2. 不支持querySelectorAll 就会启动内部 sizzle。下面是流程
/** 
.sizzle 通过 
chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g 
这个正则进行匹配, 
.把我们传来的参数'.test',匹配成'.test' 放到数组 
.检测浏览器是否支持getElementsByClassName 如果支持,则通过此函数返回dom,如果不支持此函数则 context.getElementsByTagName( "*" ) ,通过上下文把所有的元素选出来,在通过循环,选择className = 'test' 的元素,放入数组返回dom。 
*/

ok,以上是$('.test')的流程,如果你很迷惑,你可以看看源码,调试一下。
关于sizzle的选择器
个人认为,sizzle选择器是增强版的querySelectorAll 函数, 因为querySelectorAll 不支持 'div.test :eq(1)' 这样的selector 和css3选择!
当你的selector里面不出现nth|eq|gt|lt|first|last|even|odd 这样的字符时候, 从右向左,所谓的从右向左,比如 $('div img') 首先会把所有的img 选出来,通过parent 是div 进行过滤 。 这样很高效的原因是只进行一次dom的查询!
当你selector 出现了'eq(1)' 这样的字符的时候,就变正常了,从左向右!这是因为要对结果集进行过滤。
思考
$('div img:eq(0)') 与 $('div img').first() 哪个效率高? 个人认为 后一个高一些,因为 第一从左向右效率低下!没有测试过!理论推导!

今天大致看了下流程,具体的代码没怎么细研究!这里面好的思想值得学习和吸收
欢迎拍砖

Javascript 相关文章推荐
用roll.js实现的图片自动滚动+鼠标触动的特效
Mar 18 Javascript
JavaScript学习笔记记录我的旅程
May 23 Javascript
jQuery函数的等价原生函数代码示例
May 27 Javascript
javascript检测浏览器的缩放状态实现代码
Sep 28 Javascript
JavaScript极简入门教程(一):基础篇
Oct 25 Javascript
JavaScript中指定函数名称的相关方法
Jun 04 Javascript
jQuery  ready方法实现原理详解
Oct 19 Javascript
angular 用拦截器统一处理http请求和响应的方法
Jun 08 Javascript
微信小程序实现倒计时60s获取验证码
Apr 17 Javascript
基于vue的换肤功能的示例代码
Oct 10 Javascript
jQuery实现遍历XML节点和属性的方法示例
Apr 29 jQuery
Vue中computed、methods与watch的区别总结
Apr 10 Javascript
extjs3 combobox取value和text案例详解
Feb 06 #Javascript
js汉字转拼音实现代码
Feb 06 #Javascript
jquery解决图片路径不存在执行替换路径
Feb 06 #Javascript
JavaScript去除空格的三种方法(正则/传参函数/trim)
Feb 06 #Javascript
js中top/parent/frame概述及案例应用
Feb 06 #Javascript
ExtJS4 Grid改变单元格背景颜色及Column render学习
Feb 06 #Javascript
jquery load事件(callback/data)使用方法及注意事项
Feb 06 #Javascript
You might like
php模拟socket一次连接,多次发送数据的实现代码
2011/07/26 PHP
php获取表单中多个同名input元素的值
2014/03/20 PHP
PHP实现获取FLV文件的时间
2015/02/10 PHP
php输入数据统一类实例
2015/02/23 PHP
javascript之dhDataGrid Ver2.0.0代码
2007/07/01 Javascript
jquery 弹出层实现代码
2009/10/30 Javascript
关于javascript中this关键字(翻译+自我理解)
2010/10/20 Javascript
JS对话框_JS模态对话框showModalDialog用法总结
2014/01/11 Javascript
javascript使用数组的push方法完成快速排序
2014/09/15 Javascript
JS实现带缓冲效果打开、关闭、移动一个层的方法
2015/05/09 Javascript
bootstrap3 兼容IE8浏览器!
2016/05/02 Javascript
让axios发送表单请求形式的键值对post数据的实例
2018/08/11 Javascript
移动端图片上传旋转、压缩问题的方法
2018/10/16 Javascript
微信小程序的引导页实现代码
2020/06/24 Javascript
[01:48]DOTA2 2015国际邀请赛中国区预选赛第二日战报
2015/05/27 DOTA
Python Tkinter简单布局实例教程
2014/09/03 Python
python实现带错误处理功能的远程文件读取方法
2015/04/29 Python
21行Python代码实现拼写检查器
2016/01/25 Python
Python中super()函数简介及用法分享
2016/07/11 Python
python 创建一维的0向量实例
2019/12/02 Python
使用gunicorn部署django项目的问题
2020/12/30 Python
跑步爱好者一站式服务网站:Jack Rabbit
2016/09/01 全球购物
美国百年历史早餐食品供应商:Wolferman’s
2017/01/18 全球购物
新西兰床上用品和家居用品购物网站:Adairs
2018/04/27 全球购物
法国滑雪假期的专家:Ski Planet
2019/11/02 全球购物
英国最大的在线照明商店:Litecraft
2020/08/31 全球购物
招聘单位介绍信
2014/01/14 职场文书
加拿大探亲邀请信
2014/01/28 职场文书
王老吉广告词
2014/03/20 职场文书
大学学习计划书范文
2014/05/02 职场文书
2015年五四青年节活动总结
2015/02/10 职场文书
学历证明范文
2015/06/16 职场文书
创业计划书之外语培训班
2019/11/02 职场文书
天谕手游15杯全调酒配方和调酒券的获得方式
2022/04/06 其他游戏
详解CSS中postion和opacity及cursor的特性
2022/08/14 HTML / CSS