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 相关文章推荐
Jquery的hover方法让鼠标经过li时背景变色
Sep 06 Javascript
js jq 单击和双击区分示例介绍
Nov 05 Javascript
js监听滚动条滚动事件使得某个标签内容始终位于同一位置
Jan 24 Javascript
js中的caller和callee属性介绍和例子
Jun 07 Javascript
jQuery使用post方法提交数据实例
Mar 25 Javascript
移动Web中图片自适应的两种JavaScript解决方法
Jun 18 Javascript
jQuery实现带滚动导航效果的全屏滚动相册实例
Jun 19 Javascript
JS获取子窗口中返回的数据实现方法
May 28 Javascript
RGB和YUV 多媒体编程基础详细介绍
Nov 04 Javascript
微信小程序 Windows2008 R2服务器配置TLS1.2方法
Dec 05 Javascript
JavaScript装饰者模式原理与用法实例详解
Mar 09 Javascript
7个你应该知道的JS原生错误类型
Apr 29 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 操作文件的一些FAQ总结
2009/02/12 PHP
PHP和javascript常用正则表达式及用法实例
2014/07/01 PHP
PHP脚本自动识别验证码查询汽车违章
2016/12/20 PHP
AngularJS模块管理问题的非常规处理方法
2015/04/29 Javascript
js实现简单的碰壁反弹效果
2016/08/30 Javascript
JAVA Web实时消息后台服务器推送技术---GoEasy
2016/11/04 Javascript
微信小程序的动画效果详解
2017/01/18 Javascript
原生js开发的日历插件
2017/02/04 Javascript
jQuery 实时保存页面动态添加的数据的示例
2017/08/14 jQuery
原生js的ajax和解决跨域的jsonp(实例讲解)
2017/10/16 Javascript
jQuery中复合选择器简单用法示例
2018/03/31 jQuery
JS数组的高级使用方法示例小结
2020/03/14 Javascript
[02:12]2015国际邀请赛 SHOWOPEN
2015/08/05 DOTA
[42:32]VP vs RNG 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.21.mp4
2020/07/19 DOTA
python实现ftp客户端示例分享
2014/02/17 Python
详细介绍Ruby中的正则表达式
2015/04/10 Python
Django框架中数据的连锁查询和限制返回数据的方法
2015/07/17 Python
将Python代码打包为jar软件的简单方法
2015/08/04 Python
详解Python中最难理解的点-装饰器
2017/04/03 Python
快速解决pandas.read_csv()乱码的问题
2018/06/15 Python
python 遍历列表提取下标和值的实例
2018/12/25 Python
Python对ElasticSearch获取数据及操作
2019/04/24 Python
Django集成celery发送异步邮件实例
2019/12/17 Python
Python+opencv+pyaudio实现带声音屏幕录制
2019/12/23 Python
如何导出python安装的所有模块名称和版本号到文件中
2020/06/05 Python
css3的@media属性实现页面响应式布局示例代码
2014/02/10 HTML / CSS
利用HTML5+CSS3实现3D转换效果实例详解
2017/05/02 HTML / CSS
CSS3实现彩色进度条动画的示例
2020/10/29 HTML / CSS
全球最大的生存食品、水和装备专用在线市场:BePrepared.com
2020/01/02 全球购物
C/C++程序员常见面试题二
2015/11/19 面试题
RealTek面试题
2016/06/28 面试题
应届毕业生自荐书
2014/06/18 职场文书
党组织关系的介绍信模板
2019/06/21 职场文书
Nginx实现高可用集群构建(Keepalived+Haproxy+Nginx)
2021/05/27 Servers
python中的mysql数据库LIKE操作符详解
2021/07/01 MySQL
Python编写nmap扫描工具
2021/07/21 Python