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 相关文章推荐
MSN消息提示类
Sep 05 Javascript
利用js获取服务器时间的两个简单方法
Jan 08 Javascript
js 编写规范
Mar 03 Javascript
Javascript计算两个marker之间的距离(Google Map V3)
Apr 26 Javascript
Node.js入门教程:在windows和Linux上安装配置Node.js图文教程
Aug 14 Javascript
实例讲解javascript注册事件处理函数
Jan 09 Javascript
jQuery添加和删除输入文本框标签代码
May 20 Javascript
js改变css样式的三种方法推荐
Jun 28 Javascript
详解从Node.js的child_process模块来学习父子进程之间的通信
Mar 27 Javascript
jQuery EasyUI 为Combo,Combobox添加清除值功能的实例
Apr 13 jQuery
vue2.0结合Element实现select动态控制input禁用实例
May 12 Javascript
axios发送post请求,提交图片类型表单数据方法
Mar 16 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
mongo Table类文件 获取MongoCursor(游标)的实现方法分析
2013/07/01 PHP
[原创]用javascript实现检测指定目录是否存在的方法
2008/01/12 Javascript
Javascript的构造函数和constructor属性
2010/01/09 Javascript
js内存泄露的几种情况详细探讨
2013/05/31 Javascript
jQuery实现可收缩展开的级联菜单实例代码
2013/11/27 Javascript
jquery插件jTimer(jquery定时器)使用方法
2013/12/23 Javascript
node.js使用cluster实现多进程
2016/03/17 Javascript
js原型链与继承解析(初体验)
2016/05/09 Javascript
微信小程序之数据双向绑定与数据操作
2017/05/12 Javascript
vue 将页面公用的头部组件化的方法
2017/12/18 Javascript
vue将时间戳转换成自定义时间格式的方法
2018/03/02 Javascript
jQuery实现百度图片移入移出内容提示框上下左右移动的效果
2018/06/05 jQuery
浅析Proxy可以优化vue的数据监听机制问题及实现思路
2018/11/29 Javascript
vue开发环境配置跨域的方法步骤
2019/01/16 Javascript
Vue实现购物车实例代码两则
2020/05/30 Javascript
Vue.js暴露方法给WebView的使用操作
2020/09/07 Javascript
JavaScript实现无限轮播效果
2020/11/19 Javascript
vue使用exif获取图片经纬度的示例代码
2020/12/11 Vue.js
[01:02]DOTA2上海特锦赛SHOWOPEN
2016/03/25 DOTA
Python实现给文件添加内容及得到文件信息的方法
2015/05/28 Python
python装饰器实例大详解
2017/10/25 Python
Python使用Matplotlib模块时坐标轴标题中文及各种特殊符号显示方法
2018/05/04 Python
python剪切视频与合并视频的实现
2020/03/03 Python
基于HTML5的WebGL实现json和echarts图表展现在同一个界面
2017/10/26 HTML / CSS
购买英国原创艺术:Art Gallery
2018/08/25 全球购物
怎样从/向数据文件读/写结构
2014/11/23 面试题
写clone()方法时,通常都有一行代码,是什么?
2012/10/31 面试题
日化店促销方案
2014/03/26 职场文书
主要负责人任命书
2014/06/06 职场文书
乡镇消防安全责任书
2014/07/23 职场文书
小学假期安全广播稿
2014/09/28 职场文书
2014年敬老院工作总结
2014/12/08 职场文书
饭店服务员岗位职责
2015/02/09 职场文书
PL350与SW11的比较
2021/04/22 无线电
JDK8中String的intern()方法实例详细解读
2022/09/23 Java/Android
table不让td文字溢出操作方法
2022/12/24 HTML / CSS