当前位置:u赢电竞手机版 > u赢电竞竞猜app > JQuery选择器Sizzle词法分析器的理解【u赢电竞竞猜

JQuery选择器Sizzle词法分析器的理解【u赢电竞竞猜

文章作者:u赢电竞竞猜app 上传时间:2019-05-14

Sizzle 的简介:

Sizzle是jquery 中,内部实现选择器词法分析的对象,而tokenize 则是将类似 div .classname > a:[attrname=name] 这样的选择器,经过序列化成一个数组,里面的每个单元是一个标签 可以是 tag,classname,连接符[> 等],最终返回这个数组,供之后使用。

在jQuery的选择器当中,

document.getElementById,
document.getElemetByTagName,

document.getElementByClassName,
document.querySelector,
document.querySelectorAll,

等原生的选择器接口,jQ 先去查询这些接口,

elem = document.getElementById( match[2] );

u赢电竞竞猜app 1

若是不兼容这接口,则会去调用自己的实现的选择器Sizzle。

而这些css选择器,在词法解析过程中,会将每个选择器分解成字符,每个字符为一个单元

每个成员单元的结构是:

过滤器结构:TAG CLASS ATTR CHILD PSEUDO 

{
    matches: [ "div" ],
    type: "TAG",
    value: "div"
}

 

或 是连接符  ">" ," " ," " ,"~"

{
    type: ">"
    value: " > "
}

 

Sizzle 的tokenize 源码:

tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
    var matched, match, tokens, type,
        soFar, groups, preFilters,
        cached = tokenCache[ selector   " " ];

    if ( cached ) {
        return parseOnly ? 0 : cached.slice( 0 );
    }

    soFar = selector;
    groups = [];
    preFilters = Expr.preFilter; //预处理方法

    while ( soFar ) {

        // Comma and first runif ( !matched || (match = rcomma.exec( soFar )) ) {
            if ( match ) {
                // Don't consume trailing commas as valid
                soFar = soFar.slice( match[0].length ) || soFar;

            }
            groups.push( (tokens = []) );
        }

        matched = false;

        // Combinators// 匹配连接符号 ">" ," " ," " ,"~" if ( (match = rcombinators.exec( soFar )) ) {
            matched = match.shift();
            tokens.push({
                value: matched,
                // Cast descendant combinators to spacetype:match[0].replace( rtrim, " " )
            });
            soFar = soFar.slice( matched.length );
        }

        // Filters
     // 匹配过滤器:TAG CLASS ATTR CHILD PSEUDO for ( typeinExpr.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 );
            }
        }

        //到这里,第一个字符还没有捕获到对应的解析结果,那么退出if ( !matched ) {
            break;
        }
    }

    // Return the length of the invalid excess// if we're just parsing// Otherwise, throw an error or return tokens
// 如果是转换 返回选择器未 成功匹配的长度,否则把token返回,同时抛出错误。return parseOnly ?
        soFar.length :
        soFar ?
            Sizzle.error( selector ) :
            // Cache the tokens
            tokenCache( selector, groups ).slice( 0 );
};

 

Sizzle匹配的流程:

选择器:

e.g. 

选择器selector  : div > p .alen input[type='radio'],div > p .alen input[type='checkbox']

1.首先,第一个标签 div ,不是连接符号,在filter过滤时查找到

2,然后匹配第二字符,为">" ,在Combinators 匹配时查找到

 

3.之后依次匹配第一个字符是否为逗号[是则分组],是否为conbinator[">" ," " ," " ,"~"] ,或者filter中的元素 TAG CLASS ATTR CHILD PSEUDO[伪元素] ...

 

**Sizzle匹配的结果**:

u赢电竞竞猜app 2

 

总结:在看Aaron的JQuery的源码解析,和jQuery 的源码 ,个中有许多不解的地方,写写blog捋下思路。

参考:

本文由u赢电竞手机版发布于u赢电竞竞猜app,转载请注明出处:JQuery选择器Sizzle词法分析器的理解【u赢电竞竞猜

关键词: