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 相关文章推荐
js不是基础的基础
Dec 24 Javascript
javascript 对象比较实现代码
Apr 27 Javascript
显示js对象所有属性和方法的函数
Oct 16 Javascript
jquery中通过父级查找进行定位示例
Jun 28 Javascript
javascript实现yield的方法
Nov 06 Javascript
js实现将选中值累加到文本框的方法
Aug 12 Javascript
javascript嵌套函数和在函数内调用外部函数的区别分析
Jan 31 Javascript
浅析Bootstrap表格的使用
Jun 23 Javascript
JavaScript实现选中文字提示新浪微博分享效果
Jun 15 Javascript
12个提高JavaScript技能的概念(小结)
May 09 Javascript
了解JavaScript中let语句
May 30 Javascript
在vue中根据光标的显示与消失实现下拉列表
Sep 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封装的HttpClient类用法实例
2015/06/17 PHP
ucenter中词语过滤原理分析
2016/07/13 PHP
浅谈PHP中静态方法和非静态方法的相互调用
2016/10/04 PHP
解决windows上php xdebug 无法调试的问题
2020/02/19 PHP
firefox firebug中文入门教程 脚本之家新年特别版
2010/01/02 Javascript
JsDom 编程小结
2011/08/09 Javascript
用jquery和json从后台获得数据集的代码
2011/11/07 Javascript
javascript学习笔记(十三) js闭包介绍(转)
2012/06/20 Javascript
图片无缝滚动代码(向左/向下/向上)
2013/04/10 Javascript
javascript Event对象详解及使用示例
2013/11/22 Javascript
用JavaScript来美化HTML的select标签的下拉列表效果
2015/11/17 Javascript
jQuery fadeOut 异步实例代码详解
2016/08/18 Javascript
bootstrap侧边栏圆点导航
2017/01/11 Javascript
jquery uploadify如何取消已上传成功文件
2017/02/08 Javascript
js精确的加减乘除实例
2017/11/14 Javascript
Element Input组件分析小结
2018/10/11 Javascript
vue插槽slot的理解和使用方法
2019/04/03 Javascript
详解微信小程序实现跑马灯效果(附完整代码)
2019/04/29 Javascript
Nodejs环境实现socket通信过程解析
2020/07/03 NodeJs
Python的标准模块包json详解
2017/03/13 Python
使用Python对MySQL数据操作
2017/04/06 Python
浅析Python中return和finally共同挖的坑
2017/08/18 Python
python3实现爬取淘宝美食代码分享
2018/09/23 Python
Scrapy框架实现的登录网站操作示例
2020/02/06 Python
使用Python实现牛顿法求极值
2020/02/10 Python
python3访问字典里的值实例方法
2020/11/18 Python
CSS+jQuery+PHP+MySQL实现的在线答题功能
2015/04/25 HTML / CSS
解决HTML5手机端页面缩放的问题
2017/10/27 HTML / CSS
会计助理的岗位职责
2013/11/29 职场文书
劳资专员岗位职责
2013/12/27 职场文书
高中军训感言1000字
2014/03/01 职场文书
募捐倡议书
2014/04/14 职场文书
2015大学生实训报告
2014/11/05 职场文书
优秀校长事迹材料
2014/12/24 职场文书
2015年读书月活动总结
2015/03/26 职场文书
Python基本知识点总结
2022/04/07 Python