//得到由选择器生成的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方法的更多相关文章

  1. jQuery源码——.html()方法原理解析

    在将字符串转化为html碎片时,一般会将字符串作为容器的innerHTML属性赋值.但innerHTML有很多局限性,比如我们想转化的字符串中有<script>标签并且包含一个立即执行的函 ...

  2. jQuery 源码解析二:jQuery.fn.extend=jQuery.extend 方法探究

    终于动笔开始 jQuery 源码解析第二篇,写文章还真是有难度,要把自已懂的表述清楚,要让别人听懂真的不是一见易事. 在 jQuery 源码解析一:jQuery 类库整体架构设计解析 一文,大致描述了 ...

  3. jQuery源码分析系列

    声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://git ...

  4. jQuery源码学习感想

    还记得去年(2015)九月份的时候,作为一个大四的学生去参加美团霸面,结果被美团技术总监教育了一番,那次问了我很多jQuery源码的知识点,以前虽然喜欢研究框架,但水平还不足够来研究jQuery源码, ...

  5. Jquery源码学习(第一天)

    jQuery是面向对象的设计通过window.$ = window.jQuery = $; 向外提供接口,将$挂在window下,外部就可以使用$和jQuery $("#div1" ...

  6. jQuery源码 Ajax模块分析

    写在前面: 先讲讲ajax中的相关函数,然后结合函数功能来具体分析源代码. 相关函数: >>ajax全局事件处理程序 .ajaxStart(handler) 注册一个ajaxStart事件 ...

  7. jQuery源码:从原理到实战

    jQuery源码:从原理到实战 jQuery选择器对象 $(".my-class"); document.querySelectorAll*".my-class" ...

  8. 【菜鸟学习jquery源码】数据缓存与data()

    前言 最近比较烦,深圳的工作还没着落,论文不想弄,烦.....今天看了下jquery的数据缓存的代码,参考着Aaron的源码分析,自己有点理解了,和大家分享下.以后也打算把自己的jquery的学习心得 ...

  9. 从jquery源码中看类型判断和数组的一些操作

    在深入看jquery源码中,大家会发现源码写的相当巧妙.那我今天也通过几个源码中用到的技巧来抛砖引玉,希望大家能共同研究源码之精华,不要囫囵吞枣. 1.将类数组转化成数组 我想大家首先想到的方法是fo ...

  10. 读艾伦的jQuery的无new构建,疑惑分析——jquery源码学习一

    背景: 有心学习jquery源码,苦于自己水平有限,若自己研究,耗时耗力,且读懂之日无期. 所以,网上寻找高手的源码分析.再经过自己思考,整理,验证.以求有所收获. 此篇为读高手艾伦<jQuer ...

随机推荐

  1. update 操作用法

    --update 这个字段的所值为2 update tab a set a.字段1=2; --带条件的update update tab a set a.字段1=2 where id=10000; - ...

  2. (转) MVC 中 @help 用法

    ASP.NET MVC 3支持一项名为“Razor”的新视图引擎选项(除了继续支持/加强现有的.aspx视图引擎外).当编写一个视图模板时,Razor将所需的字符和击键数减少到最小,并保证一个快速.通 ...

  3. codevs 1012

    题目描述 Description 给出n和n个整数,希望你从小到大给他们排序 输入描述 Input Description 第一行一个正整数n 第二行n个用空格隔开的整数 输出描述 Output De ...

  4. [翻译Joel On Software]选择一门语言/Choosing a language

    Joel on Software Choosing a language 选择一门语言 by Joel Spolsky Sunday, May 05,2002 Why do developerscho ...

  5. MDX示例:求解中位数、四分位数(median、quartile)

    一个人力资源咨询集团通过网络爬虫采集手段将多个知名招聘网站上发布的求职和招聘等信息准实时采集到自己的库里,形成一个数据量浩大的招聘信息库,跟踪全国招聘和求职的行业.工种.职位.待遇等信息,并通过商业智 ...

  6. A River Runs Through It

           Our birth is but a sleep and a forgetting:   The Soul that rises with us, our life's Star,    ...

  7. Eclipse C++,Cygwin 64,gcov,lcov 单体&覆盖率测试环境搭建笔记

    1.下载并安装 Eclipse IDE for C/C++ Developers https://eclipse.org/downloads/packages/eclipse-ide-cc-devel ...

  8. ActiveMQ5.0实战三:使用Spring发送,消费topic和queue消息

    实战一 , 实战二 介绍了ActiveMQ的基本概念和配置方式. 本篇将通过一个实例介绍使用spring发送,消费topic, queue类型消息的方法. 不懂topic和queue的google 之 ...

  9. C#图片处理,缩略图制作

    准备参数:图片文件流.文件名 方法:1.先将图片流通过System.Drawing.Image.FromStream方法转成图片对象 2.通过图片对象.GetThumbnailImage方法生成自定义 ...

  10. 爬虫Scrapy指令学习

    1.新建一个新的爬虫项目指令 scrapy startproject xxx 2.在项目/spider目录下创建一个名为XXX的爬虫,并指定爬取域的范围  scrapy genspider XXX & ...