上篇说道,tokenize方法会把selector切割成一个个selector逻辑单元(如div>a是三个逻辑单元 'div','>','a')并为之片段赋予相应类型的过滤函数。

  1. for ( type in Expr.filter ) {
  2. if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
  3. (match = preFilters[ type ]( match ))) ) {
  4. matched = match.shift();
  5. tokens.push({
  6. value: matched,
  7. type: type,
  8. matches: match
  9. });
  10. soFar = soFar.slice( matched.length );
  11. }
  12. }
然后选出最后selector逻辑单元(是指由须要上下文的选择器,如id,tag,class等)所相应的元素集作为从右向左(普通情况)过滤的候选元素集,match(正则捕获组)是selector逻辑片段的解析结果(如[arr="111"]依据正则解析为arr,",=,111 ),在selector逻辑片段是ATTR、CHILD、PSEUDO是须要调用preFilter对match进行修正.
  1. preFilter: {
  2. //match是捕获组
  3. //如果:[arr^='val']
  4. "ATTR": function( match ) {
  5. //attr的第一个捕获 组是arr,将当中的转码变成原来的字符
  6. match[1] = match[1].replace( runescape, funescape );
  7.  
  8. // Move the given value to match[3] whether quoted or unquoted
  9. // 将val放到捕获组3里,原来的捕获组3捕获'或"
  10. match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape );
  11. //如果捕获组2是~=。在match[3]前后加空格,以方便匹配单个单词
  12. if ( match[2] === "~=" ) {
  13. match[3] = " " + match[3] + " ";
  14. }
  15. //match[0] = '[arr^='val']'
  16. //match[1] = 'arr'
  17. //match[2] = '='
  18. //match[3] = '111'
  19. return match.slice( 0, 4 );
  20. },
  21.  
  22. "CHILD": function( match ) {
  23. /* 比如nth-child(-2n+1)的捕获组
  24. mathc[1] nth
  25. mathc[2] child
  26. mathc[3] 2n+1
  27. mathc[4] 2n
  28. mathc[5] -
  29. mathc[6] 2
  30. mathc[7] +
  31. mathc[8] 1
  32. */
  33. match[1] = match[1].toLowerCase();
  34. // nth必须须要參数
  35. if ( match[1].slice( 0, 3 ) === "nth" ) {
  36. // nth-* requires argument
  37. if ( !match[3] ) {
  38. Sizzle.error( match[0] );
  39. }
  40.  
  41. // numeric x and y parameters for Expr.filter.CHILD
  42. // remember that false/true cast respectively to 0/1
  43. // xn + y
  44. // 将even,odd修正为xn+y,match[4]修正为+-x
  45. match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
  46. // 将match[5]替换为+-y
  47. match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
  48.  
  49. // other types prohibit arguments
  50. // 除nth外其它类型禁止參数
  51. } else if ( match[3] ) {
  52. Sizzle.error( match[0] );
  53. }
  54. // match[0] :nth-child(-2n+1)
  55. // match[1] nth
  56. // match[2] child
  57. // match[3] -2n+1
  58. // match[4] -2
  59. // match[5] 1
  60. // match[6] 2
  61. // match[7] +
  62. // match[8] 1
  63. return match;
  64. },
  65. /**
  66. * match[1] :后伪类类型
  67. * match[2] 伪类參数
  68. * match[3] 參数中的'或者"
  69. * match[4] 除去'或"的伪类
  70. */
  71. "PSEUDO": function( match ) {
  72. var excess,
  73. unquoted = !match[5] && match[2];
  74.  
  75. //是CHILD伪类。返回null
  76. if ( matchExpr[ "CHILD"].test( match[0] ) ) {
  77. return null;
  78. }
  79.  
  80. // Accept quoted arguments as-is
  81. // 參数有引號
  82. //将match[2]替换为无引號的match[4]參数
  83. if ( match[3] && match[4] !== undefined ) {
  84. match[2] = match[4];
  85.  
  86. // Strip excess characters from unquoted arguments
  87. // 除去带引號的參数的多余字符
  88. } else if ( unquoted && rpseudo.test( unquoted ) &&
  89. // Get excess from tokenize (recursively)
  90. //excess多余字符的长度
  91. (excess = tokenize( unquoted, true )) &&
  92. //excess多余參数的索引位置,excess是个负值,以便截取到多余字符之前
  93. (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
  94.  
  95. // excess is a negative index
  96. match[0] = match[0].slice( 0, excess );
  97. match[2] = unquoted.slice( 0, excess );
  98. }
  99.  
  100. // Return only captures needed by the pseudo filter method (type and argument)
  101. return match.slice( 0, 3 );
  102. }
  103. }

JQuery日记_5.14 Sizzle选择器(七)的更多相关文章

  1. JQuery日记_5.13 Sizzle选择器(六)选择器的效率

        当选择表达式不符合高速匹配(id,tag,class)和原生QSA不可用或返回错误时,将调用select(selector, context, results, seed)方法,此方法迭代DO ...

  2. JQuery日记 5.11 Sizzle选择器(五)

    //设置当前document和document相应的变量和方法 setDocument = Sizzle.setDocument = function( node ) { var hasCompare ...

  3. [转]JQuery - Sizzle选择器引擎原理分析

    原文: https://segmentfault.com/a/1190000003933990 ---------------------------------------------------- ...

  4. jQuery源码分析系列(三)Sizzle选择器引擎-下

    选择函数:select() 看到select()函数,if(match.length === 1){}存在的意义是尽量简化执行步骤,避免compile()函数的调用. 简化操作同样根据tokenize ...

  5. jQuery-1.9.1源码分析系列(三) Sizzle选择器引擎——编译原理

    这一节要分析的东东比较复杂,篇幅会比较大,也不知道我描述后能不能让人看明白.这部分的源码我第一次看的时候也比较吃力,现在重头看一遍,再分析一遍,看能否查缺补漏. 看这一部分的源码需要有一个完整的概念后 ...

  6. jQuery-1.9.1源码分析系列(三) Sizzle选择器引擎——总结与性能分析

    Sizzle引擎的主体部分已经分析完毕了,今天为这部分划一个句号. a. Sizzle解析流程总结 是时候该做一个总结了.Sizzle解析的流程已经一目了然了. 1.选择器进入Sizzle( sele ...

  7. Sizzle选择器引擎介绍

    一.前言 Sizzle原来是jQuery里面的选择器引擎,后来逐渐独立出来,成为一个独立的模块,可以自由地引入到其他类库中.我曾经将其作为YUI3里面的一个module,用起来畅通无阻,没有任何障碍. ...

  8. JavaScipt 源码解析 Sizzle选择器

    jQuery的定位就是一个DOM的操作库,那么可想而知选择器是一个至关重要的模块.Sizzle,作为一个独立全新的选择器引擎,出现在jQuery 1.3版本之后,并被John Resig作为一个开源的 ...

  9. jQuery源码学习:Sizzle

    本文所有讨论均基于jQuery版本3.1.1,官网http://jquery.com/. 一 简介 Sizzle是用javascript实现的CSS selector engine,官网见https: ...

随机推荐

  1. [ Openstack ] Openstack-Mitaka 高可用之 环境初始化

    目录 Openstack-Mitaka 高可用之 概述    Openstack-Mitaka 高可用之 环境初始化    Openstack-Mitaka 高可用之 Mariadb-Galera集群 ...

  2. 某dp题2

    P2401 不等数列 题目描述 将1到n任意排列,然后在排列的每两个数之间根据他们的大小关系插入">"和"<".问在所有排列中,有多少个排列恰好有k ...

  3. 使用DRF视图集时自定义action方法

    在我们用DRF视图集完成了查找全部部门,创建一个新的部门,查找一个部门,修改一个部门,删除一个部门的功能后,views.py的代码是这样子的: class DepartmentViewSet(Mode ...

  4. Mysql缺少可执行的命令

    MySQL问题解决:-bash:mysql:command not found 问题:       [root@linux115 /]# mysql -uroot -p        -bash: m ...

  5. k8s的Health Check(健康检查)

    强大的自愈能力是 Kubernetes 这类容器编排引擎的一个重要特性.自愈的默认实现方式是自动重启发生故障的容器.除此之外,用户还可以利用 Liveness 和 Readiness 探测机制设置更精 ...

  6. yii2.0在model里自定义数据表

    无需多言,直接撸代码 class Zhuanjia extends \yii\db\ActiveRecord { public static function tableName() { return ...

  7. 服务器重启之后wdcp打不开【解决】

    service wdapache restart

  8. The 15th Zhejiang Provincial Collegiate Programming Contest Sponsored by TuSimple -A Peak

    Peak Time Limit: 1 Second      Memory Limit: 65536 KB A sequence of  integers  is called a peak, if ...

  9. jmeter 线程组之间的参数传递

    http://www.cnblogs.com/wnfindbug/p/5817277.html 场景测试中,一次登录后做多个接口的操作,然后登录后的uid需要关联传递给其他接口发送请求的时候使用. 1 ...

  10. 【计算几何】【凸包】bzoj2829 信用卡凸包

    http://hzwer.com/6330.html #include<cstdio> #include<cmath> #include<algorithm> us ...