【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 ...
随机推荐
- MFC中不同对话框间使用SendMessage发送自定义消息的具体实现
1. 基本知识 SendMessage的基本结构如下: SendMessage( HWND hWnd, //消息传递的目标窗口或线程的句柄. UINT Msg, //消息类别(这里可 ...
- Elasticsearch 相关 api 操作
A. es 操作 1. 检查 es 集群健康状态 2. 获取集群中的节点列表 3. 创建索引 4. 获取索引 5. 索引文档 6. 查询文档 7. 删除索引 8. 更新文档 9. 删除文档 10. 批 ...
- 【TFS 2017】使用浏览器上传文件(TFVC)或者编辑代码,错误提示TF14098,需要对文件有PendChange 权限
从TFS 2015开始,微软在TFS系统中增加了一个非常吸引开发人员的功能,"快速代码编辑器" (Quick Code Editor).使用这个功能,你可以在任何安装了浏览器的设备 ...
- DAC--解决windows验证无法登陆的问题
解决思路: 使用单用户管理员模式启动SQL Server,再使用SQLCMD连接上数据库,此时有sysadmin权限,添加用户并赋予相应权限 1>停止SQL Server服务运行 2>在C ...
- NERDTree基本使用教程
Vim插件之属性目录NERDTree 1.下载安装 下载地址: 官网:http://www.vim.org/scripts/script.php?script_id=1658 GitHib:htt ...
- 解决 EntityFrameworkCore 执行 Add-Migration命令提示无法识别转义符的错误
版本.asp.net core 2.0 EntityFrameworkCore2,0,. 之前执行Add-Migration 命令 提示无法识别的转义序列,各种不成功, 解决办法,找到 项目里面的 ...
- EF简易教程,从建表到表间关系
唐大兵博客 唐大兵的博客里记录了EF Code First从建表到表之间关系的详细内容. 汪杰的博客(EF里一对一.一对多.多对多关系的配置和级联删除) 汪杰的博客更简洁,但不够充实,读懂了唐大兵博客 ...
- python小数的进位与舍去
一.基础知识准备 奇进偶舍,又称为四舍六入五成双规则.银行进位法(Banker's Rounding),是一种计数保留法,是一种数值修约规则.从统计学的角度,"奇进偶舍"比&q ...
- Xcode的多种Build Configuration
一: 建多个Configuration的目的. 多套域名打包. 1 开发时的域名. 2 内测时的域名. 3 公测时的域名. 4 企业版的域名. 5 APP Store的域名. 通过注释的方式,容易出错 ...
- hdoj1575 Tr A(矩阵快速幂)
简单的矩阵快速幂.最后求矩阵的秩. #include<iostream> #include<cstring> using namespace std; ; int n,k; s ...