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实现学校的校历(asp.net+jquery ui 1.72)
Jan 01 Javascript
前端js文件合并的三种方式推荐
May 19 Javascript
js仿小米官网图片轮播特效
Sep 29 Javascript
jquery操作ID带有变量的节点实例
Dec 07 Javascript
学习使用Bootstrap栅格系统
May 11 Javascript
vue2.0 keep-alive最佳实践
Jul 06 Javascript
angular+ionic返回上一页并刷新页面
Aug 08 Javascript
ES6 Iterator接口和for...of循环用法分析
Jul 31 Javascript
高性能js数组去重(12种方法,史上最全)
Dec 21 Javascript
Vue组件通信$attrs、$listeners实现原理解析
Sep 03 Javascript
JS检测浏览器开发者工具是否打开的方法详解
Oct 02 Javascript
element-ui中el-upload多文件一次性上传的实现
Dec 02 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+AJAX实现无刷新注册(带用户名实时检测)
2007/01/02 PHP
PHP操作XML作为数据库的类
2010/12/19 PHP
Linux下PHP连接Oracle数据库
2014/08/20 PHP
使用array_map简单搞定PHP删除文件、删除目录
2014/10/29 PHP
php实现图片转换成ASCII码的方法
2015/04/03 PHP
Thinkphp 3.2框架使用Redis的方法详解
2019/10/24 PHP
php多进程中的阻塞与非阻塞操作实例分析
2020/03/04 PHP
javascript innerText和innerHtml应用
2010/01/28 Javascript
jquery插件pagination实现无刷新ajax分页
2015/09/30 Javascript
js和jquery分别验证单选框、复选框、下拉框
2015/12/17 Javascript
jQuery实现点击后高亮背景固定显示的菜单效果【附demo源码下载】
2016/09/21 Javascript
JavaScript与java语言有什么不同
2016/09/22 Javascript
学习使用Bootstrap页面排版样式
2017/05/11 Javascript
Angular中管道操作符(|)的使用方法
2017/12/15 Javascript
Javascript实现一朵从含苞到绽放的玫瑰
2019/03/30 Javascript
Nuxt.js实战和配置详解
2019/08/05 Javascript
微信小程序抽奖组件的使用步骤
2021/01/11 Javascript
[34:47]完美世界DOTA2联赛PWL S2 Magma vs LBZS 第一场 11.18
2020/11/18 DOTA
python中 ? : 三元表达式的使用介绍
2013/10/09 Python
Python文件的读写和异常代码示例
2017/10/31 Python
用tensorflow实现弹性网络回归算法
2018/01/09 Python
Python获取指定字符前面的所有字符方法
2018/05/02 Python
基于python 爬虫爬到含空格的url的处理方法
2018/05/11 Python
python 每天如何定时启动爬虫任务(实现方法分享)
2018/05/21 Python
Python实现变声器功能(萝莉音御姐音)
2019/12/05 Python
python使用scapy模块实现ping扫描的过程详解
2021/01/21 Python
酒店拾金不昧表扬信
2014/01/18 职场文书
2014年国庆节演讲稿
2014/09/02 职场文书
中共广东省委常委会党的群众路线教育实践活动整改方案
2014/09/23 职场文书
2014基建处领导班子“四风”对照检查材料思想汇报
2014/10/04 职场文书
大三学生英语考试作弊检讨书
2015/01/01 职场文书
新娘父亲婚礼致辞
2015/07/27 职场文书
2016年五一劳动节专题校园广播稿
2015/12/17 职场文书
如何搭建 MySQL 高可用高性能集群
2021/06/21 MySQL
MySQL系列之十 MySQL事务隔离实现并发控制
2021/07/02 MySQL
js前端设计模式优化50%表单校验代码示例
2022/06/21 Javascript