【jQuery源码】tokenize方法
//得到由选择器生成的token对象的数组(下面的groups)
//Sizzle的Token格式如下 :{value:'匹配到的字符串', type:'对应的Token类型', matches:'正则匹配到的一个结构'}
//比如"title,div > :nth-child(even)"解析下面的符号流
// [ [{value:"title",type:"TAG",matches:["title"]}],
// [{value:"div",type:["TAG",matches:["div"]},
// {value:">", type: ">"},
// {value:":nth-child(even)",type:"CHILD",matches:["nth",
// "child","even",2,0,undefined,undefined,undefined]}
// ]
// ]
//有多少个并联选择器,里面就有多少个数组,数组里面是拥有value与type的对象 //tokenize两个作用:1.解析选择器;2.将解析结果存入缓存
tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
var matched, match, tokens, type,
soFar, groups, preFilters,
cached = tokenCache[ selector + " " ];
//这里的soFar是表示目前还未分析的字符串剩余部分 //如果tokenCache中已经有selector了,则直接拿出来就好了
if ( cached ) {
return parseOnly ? 0 : cached.slice( 0 );
} soFar = selector;
groups = []; //这里的预处理器为了对匹配到的Token适当做一些调整
preFilters = Expr.preFilter; //循环处理字符串
while ( soFar ) { // Comma and first run
//whitespace = "[\\x20\\t\\r\\n\\f]";
//rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" );
//!matched:若是第一次执行循环体,则为true;否则为false。
//这里matched即作为是否第一次执行循环体的标识,
if ( !matched || (match = rcomma.exec( soFar )) ) {
if ( match ) {
// Don't consume trailing commas as valid
//去掉sofar中第一个的无用",",比如",div,#id"中的第一个","
//举个例子,"div.news,span.closed"
//在解析过程中,首先由后续代码解析完毕div.news,剩下",span.closed"
//在循环体内执行到这里时,将逗号及之前之后连续的空白(match[0])删除掉,
//使soFar变成"span.closed",继续执行解析过程
soFar = soFar.slice( match[0].length ) || soFar;
}
//往规则组里边压入一个Token序列,目前Token序列还是空的
groups.push( (tokens = []) );
} matched = false; // Combinators
//rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*"),
//rcombinators用来匹配四种关系符,即>+~和空白
if ( (match = rcombinators.exec( soFar )) ) {
// 举个例子:
// 若soFar = " + .div";
// 执行match = rcombinators.exec(soFar)后,
// match[0] = " + ",而match[1]="+";
// 执行完matched = match.shift()后,
// matched=" + ",而match[0]="+";
matched = match.shift();
tokens.push({
value: matched,
// Cast descendant combinators to space
type: match[0].replace( rtrim, " " )
});
soFar = soFar.slice( matched.length );
} // Filters
//下面通过for语句对soFar逐一匹配ID、TAG、CLASS、CHILD、ATTR、PSEUDO类型的选择器
// 若匹配到了,则先调用该类型选择器对应的预过滤函数,
// 然后,将结果压入tokens数组,继续本次循环。
for ( type in Expr.filter ) {
// match = matchExpr[type].exec(soFar):对soFar调用type类型的正则表达式对soFar进行匹配
// 并将匹配结果赋予match。若未匹配到数据,则match为null。
// !preFilters[type]:若不存在type类型的预过滤函数,则为true
// match = preFilters[type](match):执行预过滤,并将结果返回给match
if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
(match = preFilters[ type ]( match ))) ) {
// 将match[0]移除match数组,同时将它赋予matched
matched = match.shift();
// 将匹配结果压入tokens数组中
tokens.push({
value: matched,
type: type,
matches: match
});
// 将匹配结果之后的字符串赋予soFar,继续解析
soFar = soFar.slice( matched.length );
}
} //matched为false,说明本次循环没有效的选择器(包括关系符和id、class等类型选择器)
if ( !matched ) {
break;
}
} // Return the length of the invalid excess
// if we're just parsing
// Otherwise, throw an error or return tokens
return parseOnly ?
soFar.length :
soFar ?
Sizzle.error( selector ) :
// Cache the tokens
tokenCache( selector, groups ).slice( 0 );
};
画一张直观图便于理解

【jQuery源码】tokenize方法的更多相关文章
- jQuery源码——.html()方法原理解析
在将字符串转化为html碎片时,一般会将字符串作为容器的innerHTML属性赋值.但innerHTML有很多局限性,比如我们想转化的字符串中有<script>标签并且包含一个立即执行的函 ...
- jQuery 源码解析二:jQuery.fn.extend=jQuery.extend 方法探究
终于动笔开始 jQuery 源码解析第二篇,写文章还真是有难度,要把自已懂的表述清楚,要让别人听懂真的不是一见易事. 在 jQuery 源码解析一:jQuery 类库整体架构设计解析 一文,大致描述了 ...
- jQuery源码分析系列
声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://git ...
- jQuery源码学习感想
还记得去年(2015)九月份的时候,作为一个大四的学生去参加美团霸面,结果被美团技术总监教育了一番,那次问了我很多jQuery源码的知识点,以前虽然喜欢研究框架,但水平还不足够来研究jQuery源码, ...
- Jquery源码学习(第一天)
jQuery是面向对象的设计通过window.$ = window.jQuery = $; 向外提供接口,将$挂在window下,外部就可以使用$和jQuery $("#div1" ...
- jQuery源码 Ajax模块分析
写在前面: 先讲讲ajax中的相关函数,然后结合函数功能来具体分析源代码. 相关函数: >>ajax全局事件处理程序 .ajaxStart(handler) 注册一个ajaxStart事件 ...
- jQuery源码:从原理到实战
jQuery源码:从原理到实战 jQuery选择器对象 $(".my-class"); document.querySelectorAll*".my-class" ...
- 【菜鸟学习jquery源码】数据缓存与data()
前言 最近比较烦,深圳的工作还没着落,论文不想弄,烦.....今天看了下jquery的数据缓存的代码,参考着Aaron的源码分析,自己有点理解了,和大家分享下.以后也打算把自己的jquery的学习心得 ...
- 从jquery源码中看类型判断和数组的一些操作
在深入看jquery源码中,大家会发现源码写的相当巧妙.那我今天也通过几个源码中用到的技巧来抛砖引玉,希望大家能共同研究源码之精华,不要囫囵吞枣. 1.将类数组转化成数组 我想大家首先想到的方法是fo ...
- 读艾伦的jQuery的无new构建,疑惑分析——jquery源码学习一
背景: 有心学习jquery源码,苦于自己水平有限,若自己研究,耗时耗力,且读懂之日无期. 所以,网上寻找高手的源码分析.再经过自己思考,整理,验证.以求有所收获. 此篇为读高手艾伦<jQuer ...
随机推荐
- verilog基础--altera培训
参数化 Localparam :与prameter一样,但不能被重写. Verilog-2001 格式, module mult_acc #(parameter size = 8 ) (...); 数 ...
- Windows 下使用 GCC
MinGw 是 Minimal GNU on Windows 的缩写,允许在 GNU/Linux 和 Windows 平台生成本地的 Windows 程序而不需要第三方运行时库.本文主要介绍 MinG ...
- Win窗口坐标二维坐标与OpenGl的世界坐标系的之间的相互转换
Win窗口坐标二维坐标与OpenGl的世界坐标系的转换 几何处理管线擅长于使用视图和投影矩阵以及用于裁剪的视口把顶点的世界坐标变换为窗口坐标. 但是,在有些情况下,需要逆转这个过程.一种常见的情形是: ...
- 从hbase到hive,以及sqoop转到mysql解析
https://blog.csdn.net/qq_33689414/article/details/80328665 hive关联hbase的配置文件 hive和hbase同步https://cwik ...
- A River Runs Through It
Our birth is but a sleep and a forgetting: The Soul that rises with us, our life's Star, ...
- 项目笔记---WPF多语言方案
近期由于朋友邀请帮忙给一个开源的游戏“外挂”做一个I18N的解决方案,恰好也是WPF做的,之前有过相关经验,就忙了一个星期终于搞定了,已经提交给作者了,现在这里做一个分享. 这里分享下我个人Fork的 ...
- SignalR 设计理念(二)
SignalR 设计理念(二) 实现客户端和服务器端的实时通讯. 前言: 客户端方法忽略大小写,主要原因基于是URL对大小写不敏感的问题,开发者之间为了更好的协同开发,定下的开发者协议. 问题阐述 客 ...
- HTTP响应状态码说明
当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含HTTP状态码的信息头(Server Header)用以响应浏览器的请求. HTTP状态码共分为五种类型: 1**:信息,服务器接收到请求,需 ...
- C#使用Linq对DataGridView进行模糊查找
针对DataGridView中已进行过数据绑定,即已向DataGridView中添加了一些数据,可以结合Linq查询,并让匹配查询的行高亮显示,如下图: 具体实现如下: [csharp] ...
- NetCore入门篇:(一)Net Core环境安装
一.下载Visual Studio 2017 1.下载地址:https://www.visualstudio.com/zh-hans/downloads/ 2.选择要下载的版本 二.安装Net Cor ...