zoukankan      html  css  js  c++  java
  • JQuery日记_5.14 Sizzle选择器(七)


    上篇说道,tokenize方法会把selector切割成一个个selector逻辑单元(如div>a是三个逻辑单元 'div','>','a')并为之片段赋予相应类型的过滤函数。
    for ( type in Expr.filter ) {
                   if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
                        (match = preFilters[ type ]( match ))) ) {
                        matched = match.shift();
                        tokens.push({
                             value: matched,
                             type: type,
                             matches: match
                        });
                        soFar = soFar.slice( matched.length );
                   }
     }
    
    然后选出最后selector逻辑单元(是指由须要上下文的选择器,如id,tag,class等)所相应的元素集作为从右向左(普通情况)过滤的候选元素集,match(正则捕获组)是selector逻辑片段的解析结果(如[arr="111"]依据正则解析为arr,",=,111 ),在selector逻辑片段是ATTR、CHILD、PSEUDO是须要调用preFilter对match进行修正.
    preFilter: {
                 //match是捕获组
                 //如果:[arr^='val']
                 "ATTR": function( match ) {
                       //attr的第一个捕获 组是arr,将当中的转码变成原来的字符
                      match[1] = match[1].replace( runescape, funescape );
    
                       // Move the given value to match[3] whether quoted or unquoted
                       // 将val放到捕获组3里,原来的捕获组3捕获'或"
                      match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape );
                       //如果捕获组2是~=。在match[3]前后加空格,以方便匹配单个单词
                       if ( match[2] === "~=" ) {
                            match[3] = " " + match[3] + " ";
                      }
                       //match[0] = '[arr^='val']'
                       //match[1] = 'arr'
                       //match[2] = '='
                       //match[3] = '111'
                       return match.slice( 0, 4 );
                },
    
                 "CHILD": function( match ) {
                       /*  比如nth-child(-2n+1)的捕获组
                            mathc[1] nth
                            mathc[2] child
                            mathc[3] 2n+1
                            mathc[4] 2n
                            mathc[5] -
                            mathc[6] 2
                            mathc[7] +
                            mathc[8] 1
                      */
                      match[1] = match[1].toLowerCase();
                       // nth必须须要參数
                       if ( match[1].slice( 0, 3 ) === "nth" ) {
                             // nth-* requires argument
                             if ( !match[3] ) {
                                  Sizzle.error( match[0] );
                            }
    
                             // numeric x and y parameters for Expr.filter.CHILD
                             // remember that false/true cast respectively to 0/1
                             // xn + y
                             // 将even,odd修正为xn+y,match[4]修正为+-x
                            match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
                             // 将match[5]替换为+-y
                            match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
    
                       // other types prohibit arguments
                       // 除nth外其它类型禁止參数
                      } else if ( match[3] ) {
                            Sizzle.error( match[0] );
                      }
                       // match[0] :nth-child(-2n+1)
                       // match[1] nth
                       // match[2] child
                       // match[3] -2n+1
                       // match[4] -2
                       // match[5] 1
                       // match[6] 2
                       // match[7] +
                       // match[8] 1
                       return match;
                },
                 /**
                 * match[1] :后伪类类型
                 * match[2] 伪类參数
                 * match[3] 參数中的'或者"
                 * match[4] 除去'或"的伪类
                 */
                 "PSEUDO": function( match ) {
                       var excess,
                            unquoted = !match[5] && match[2];
    
                       //是CHILD伪类。返回null
                       if ( matchExpr[ "CHILD"].test( match[0] ) ) {
                             return null;
                      }
    
                       // Accept quoted arguments as-is
                       // 參数有引號
                       //将match[2]替换为无引號的match[4]參数
                       if ( match[3] && match[4] !== undefined ) {
                            match[2] = match[4];
    
                       // Strip excess characters from unquoted arguments
                       // 除去带引號的參数的多余字符
                      } else if ( unquoted && rpseudo.test( unquoted ) &&
                             // Get excess from tokenize (recursively)
                             //excess多余字符的长度
                            (excess = tokenize( unquoted, true )) &&
                             //excess多余參数的索引位置,excess是个负值,以便截取到多余字符之前
                            (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
    
                             // excess is a negative index
                            match[0] = match[0].slice( 0, excess );
                            match[2] = unquoted.slice( 0, excess );
                      }
    
                       // Return only captures needed by the pseudo filter method (type and argument)
                       return match.slice( 0, 3 );
                }
          }
    



  • 相关阅读:
    (LeetCode 141/142)Linked List Cycle
    (算法)随机播放歌曲
    (数组)数组排序,使所有奇数在左边,所有偶数在右边
    遗失的乔布斯访谈(文字版)
    幻想·梦想·理想
    立刻辞职,时不我待
    彩票漏洞让你快速致富
    剪刀石头布常胜秘笈
    9个心理学研究,让你学习更高效
    石头剪刀布手套:不止是寂寞宅的消遣
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/6758310.html
Copyright © 2011-2022 走看看