jQuery选择器源码解读(六):Sizzle选择器匹配逻辑分析


Posted in Javascript onMarch 31, 2015

近期看了一些网上关于Sizzle的分析文章,就匹配次序往往就说使用了从右到左的逆向匹配法,但是具体如何并没有详细介绍,或者就像我之前的几篇文章一样,就代码一行一行做详细介绍,但缺乏整体概念,这里就jQuery-1.10.2版本的Sizzle的匹配逻辑(预编译结果)做一整体说明,这里就不谈过多的细节了。

Sizzle的匹配过程采用的是以从右到左的逆向匹配法为基础的改进版本,因为HTML的搜索毕竟和文本匹配有差异,它有自己独特的一面,所以,需要针对HTML的搜索进行优化。在此先申明一点,下面所说的关系选择器是指W3C中的Combinator选择器,因本人觉得用关系选择器这个名字要比其它更加贴近实际意义,故用此命名。

1、简单介绍一下Sizzle编译执行的两个主要函数:

a) matcherFromTokens——针对一个块选择器生成执行函数,所谓块选择器就是不包含逗号分隔的选择器字符串。

b) matcherFromGroupMatchers——将不同的块选择器生成的最终执行函数,该函数还负责将最终结果过滤掉重复对象。

2、matcherFromTokens函数针对不同类型的选择器产生不同的执行函数。若包含伪类,则返回setMatcher,否则返回的是elementMatcher,代码通过鉴别matcher是否包含expando属性来区别setMatcher和elementMatcher:

a) 针对非伪类且非关系选择器,直接从左到右依次生成执行函数,各函数作为同一个matchers数组的不同元素存在。

b) 针对关系选择器,将会把之前生成的matchers压入一个新的matchers数组中。

c) 针对伪类选择器,将通过setMatcher函数生成一个执行函数,调用setMatcher时,依次传入6个参数,分别是preFilter, selector, matcher, postFilter, postFinder, postSelector。

      preFilter是在执行setMatcher函数之前已生成的matchers数组经elementMatcher函数加工过的最终函数,elementMatcher(matchers)将返回一个从后向前依次执行每一个matchers元素函数的新函数;。

      selector是matchers对应的选择器字符串;

      matcher是伪类自身的匹配函数;

      postFilter是伪类之后,到第一个伪类或关系符之间的选择器字符串对应的匹配函数,它是嵌套调用matcherFromTokens函数的返回结果;

      postFinder是postFilter对应选择器之后的所有选择器生成的匹配函数,同样也是通过嵌套调用matcherFromTokens函数的返回结果;

      postSelector是postFinder对应的选择器字符串。

d) 若选择器字符串中没有伪类,那么,将返回elementMatcher(matchers)生成的最终匹配函数。

从上面的介绍可以看出,生成的执行函数之间存在着嵌套关系,简单的讲就是setMatcher包含matchers,关系选择器匹配函数包含非伪类且非关系选择器匹配函数。

3、执行过程的介绍:

a) 执行块选择器的执行函数:

      针对elementMatcher,从外到里从后到前依次执行,即从最外层数组到最里层数组依次执行,同一个数组中,从最后一个元素到第一个元素依次执行。

      针对setMatcher,先依据preFilter和selector获得匹配结果;然后执行matcher函数获取匹配结果;之后,执行postFilter函数,最后,依据postFinder和postSelector获取匹配结果。

c) 依次执行每个块选择器的执行函数后,过滤掉重复数据,并返回结果。

看了上述大致过程,再去看各方法的详细介绍应该比较容易理解了,当然在这里没有谈到一些细节,例如初始结果集(seed)的生成及由此带来的函数执行逻辑细节上的差异等。

Javascript 相关文章推荐
模拟jQuery ajax服务器端与客户端通信的代码
Mar 28 Javascript
小试JQuery的AutoComplete插件
May 04 Javascript
js实现日期级联效果
Jan 23 Javascript
jQuery插件zoom实现图片全屏放大弹出层特效
Apr 15 Javascript
JavaScript控制网页平滑滚动到指定元素位置的方法
Apr 17 Javascript
JS中的Replace方法使用经验分享
May 20 Javascript
js实现拉幕效果的广告代码
Sep 02 Javascript
12个非常实用的JavaScript小技巧【推荐】
May 18 Javascript
JS实现复制内容到剪贴板功能兼容所有浏览器(推荐)
Jun 17 Javascript
Vue.js中组件中的slot实例详解
Jul 17 Javascript
微信小程序request请求后台接口php的实例详解
Sep 20 Javascript
详解vue数组遍历方法forEach和map的原理解析和实际应用
Nov 15 Javascript
jQuery选择器源码解读(五):tokenize的解析过程
Mar 31 #Javascript
JavaScript制作windows经典扫雷小游戏
Mar 31 #Javascript
jQuery选择器源码解读(四):tokenize方法的Expr.preFilter
Mar 31 #Javascript
JavaScript制作简易的微信打飞机
Mar 31 #Javascript
JS获取表格内指定单元格html内容的方法
Mar 31 #Javascript
JS实现为表格动态添加标题的方法
Mar 31 #Javascript
JS实现从表格中动态删除指定行的方法
Mar 31 #Javascript
You might like
我的论坛源代码(二)
2006/10/09 PHP
php解决抢购秒杀抽奖等大流量并发入库导致的库存负数的问题
2014/06/19 PHP
Yii Framework框架获取分类下面的所有子类方法
2014/06/20 PHP
PHP中子类重载父类的方法【parent::方法名】
2016/05/06 PHP
javascript hashtable 修正版 下载
2010/12/30 Javascript
jQuery实现的点赞随机数字显示动画效果(附在线演示与demo源码下载)
2015/12/31 Javascript
jquery+json实现动态商品内容展示的方法
2016/01/14 Javascript
分享两段简单的JS代码防止SQL注入
2016/04/12 Javascript
jQuery插件ajaxfileupload.js实现上传文件
2020/10/23 Javascript
Vuejs第十一篇组件之slot内容分发实例详解
2016/09/09 Javascript
JavaScript实现事件的中断传播和行为阻止方法示例
2017/01/20 Javascript
源码分析Vue.js的监听实现教程
2017/04/23 Javascript
JS实现预加载视频音频/视频获取截图(返回canvas截图)
2017/10/09 Javascript
webpack项目调试以及独立打包配置文件的方法
2018/02/28 Javascript
jQuery实现下拉菜单动态添加数据点击滑出收起其他功能
2018/06/14 jQuery
Vue-cli 移动端布局和动画使用详解
2020/08/10 Javascript
微信小程序自定义yPicker组件实现省市区三级联动功能
2020/10/29 Javascript
Python打印scrapy蜘蛛抓取树结构的方法
2015/04/08 Python
python比较两个列表大小的方法
2015/07/11 Python
Python脚本实现12306火车票查询系统
2016/09/30 Python
Python采集猫眼两万条数据 对《无名之辈》影评进行分析
2018/12/05 Python
Django实现学生管理系统
2019/02/26 Python
详解pandas DataFrame的查询方法(loc,iloc,at,iat,ix的用法和区别)
2019/08/02 Python
Python打印不合法的文件名
2020/07/31 Python
新加坡最受追捧的体验平台:Hapz
2018/01/01 全球购物
Pat McGrath Labs官网:世界上最有影响力的化妆师推出的彩妆品牌
2018/01/07 全球购物
佳能法国商店:Canon法国
2019/02/14 全球购物
大三自我鉴定范文
2013/10/05 职场文书
大学毕业生最详细的自我评价分享
2013/11/18 职场文书
《毛主席在花山》教学反思
2014/04/20 职场文书
2014中考励志标语
2014/06/05 职场文书
群众路线专项整治工作情况报告
2014/10/28 职场文书
2014年幼师工作总结
2014/11/22 职场文书
任长霞观后感
2015/06/16 职场文书
谢师宴学生致辞
2015/07/27 职场文书
Python 中的Sympy详细使用
2021/08/07 Python