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 相关文章推荐
优化javascript的执行速度
Jan 23 Javascript
由JavaScript技术实现的web小游戏(不含网游)
Jun 12 Javascript
jquery 动态创建元素的方式介绍及应用
Apr 21 Javascript
bootstrap3 兼容IE8浏览器!
May 02 Javascript
详解vue2.0 使用动态组件实现 Tab 标签页切换效果(vue-cli)
Aug 30 Javascript
js技巧之十几行的代码实现vue.watch代码
Jun 09 Javascript
深入理解Vue router的部分高级用法
Aug 15 Javascript
Vue封装的可编辑表格插件方法
Aug 28 Javascript
JS获取当前时间的实例代码(昨天、今天、明天)
Nov 13 Javascript
JavaScript中concat复制数组方法浅析
Jan 20 Javascript
angular4中引入echarts的方法示例
Jan 29 Javascript
vue跳转同一个组件,参数不同,页面接收值只接收一次的解决方法
Nov 05 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:风雨欲来 路在何方?
2006/10/09 PHP
IIS6.0+PHP5.x+MySQL5.x+Zend3.0x+GD+phpMyAdmin2.8x通用安装实例(已经完成)
2006/12/06 PHP
PHP 程序员也要学会使用“异常”
2009/06/16 PHP
php使用smtp发送支持附件的邮件示例
2014/04/13 PHP
一个非常实用的php文件上传类
2017/07/04 PHP
tp5框架使用composer实现日志记录功能示例
2019/01/10 PHP
ThinkPHP5.1框架页面跳转及修改跳转页面模版示例
2019/05/06 PHP
event.srcElement 用法笔记e.target
2009/12/18 Javascript
JS getMonth()日期函数的值域是0-11
2010/02/15 Javascript
javascript 用记忆函数快速计算递归函数
2010/03/15 Javascript
『jQuery』.html(),.text()和.val()的概述及使用
2013/04/22 Javascript
基于jquery的文字向上跑动类似跑马灯的效果
2014/09/22 Javascript
jquery正则表达式验证(手机号、身份证号、中文名称)
2015/12/31 Javascript
Web Uploader文件上传插件使用详解
2016/05/10 Javascript
基于javascript实现表格的简单操作
2016/05/21 Javascript
利用Jquery队列实现根据输入数量显示的动画
2016/09/01 Javascript
JavaScript中利用构造器函数模拟类的方法
2017/02/16 Javascript
jQuery插件HighCharts实现的2D堆条状图效果示例【附demo源码下载】
2017/03/14 Javascript
使用jQuery.Pin垂直滚动时固定导航
2017/05/24 jQuery
详解mpvue实现对苹果X安全区域的适配
2019/07/31 Javascript
vue实现输入一位数字转汉字功能
2019/12/13 Javascript
解决Vue中使用keepAlive不缓存问题
2020/08/04 Javascript
python thrift搭建服务端和客户端测试程序
2018/01/17 Python
python解析xml简单示例
2019/06/21 Python
python文件转为exe文件的方法及用法详解
2019/07/08 Python
python dumps和loads区别详解
2020/02/04 Python
python装饰器代码深入讲解
2021/03/01 Python
html5移动端自适应布局的实现
2020/04/15 HTML / CSS
介绍一下MD5加密算法
2016/11/12 面试题
军训自我鉴定100字
2014/02/13 职场文书
党员干部廉洁承诺书
2014/05/28 职场文书
三严三实民主生活会发言稿
2014/10/13 职场文书
2014年村官工作总结
2014/11/24 职场文书
2014年办公室文秘工作总结
2014/12/09 职场文书
高考作弊检讨书1500字
2015/02/16 职场文书
Spring Boot配合PageHelper优化大表查询数据分页
2022/04/20 Java/Android