zoukankan      html  css  js  c++  java
  • JQuery选择器Sizzle词法分析器的理解

    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] );
    若是不兼容这接口,则会去调用自己的实现的选择器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匹配的结果
     
    总结:在看Aaron的JQuery的源码解析,和jQuery 的源码 ,个中有许多不解的地方,写写blog捋下思路。
    参考:http://www.cnblogs.com/aaronjs/p/3281911.html
  • 相关阅读:
    CPP流类库与输入输出
    STL学习之mismatch();
    谷歌浏览器现在点击任何文本都会出现光标
    jQuery删除元素remove和和empty的区别
    jQuery中的鼠标离开事件mouseout和mouseleave区别
    java类中的布尔(boolean&Boolean)类型字段要注意get方法和字段的命名
    Navicat_Premium_v15 激活
    navicat注册过期修改方法
    ClassNotFoundException找不到类异常的原因package 路径eclipse自动给我在路径前面加了一个java变成了java.com.XXX
    我保存一份博客园样式代码
  • 原文地址:https://www.cnblogs.com/Alencong/p/5861593.html
Copyright © 2011-2022 走看看