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

时间: 2024-10-28 20:34:09

JQuery选择器Sizzle词法分析器的理解的相关文章

理解jQuery选择器与Sizzle

什么是jQuery选择器? jQuery选择器通俗来讲就是一个获取html元素的工具.比如,$("p") 选取 <p> 元素,$("p")是jQuery的选择器的写法,这么写就可以获取(选取)html里的<p>元素. jQuery选择器包括元素选择器.属性选择器.CSS选择器.(个人感觉这个分类比较扯淡) 注意:属性选择器的意思并不是选择属性,而是根据属性选择元素. 详细参考:http://www.w3school.com.cn/jquery

jQuery选择器引擎和Sizzle介绍

一.前言 Sizzle原来是jQuery里面的选择器引擎,后来逐渐独立出来,成为一个独立的模块,可以自由地引入到其他类库中.我曾经将其作为YUI3里面的一个module,用起来畅通无阻,没有任何障碍.Sizzle发展到现在,以jQuery1.8为分水岭,大体上可以分为两个阶段,后面的版本中引入了编译函数的概念,Sizzle的源码变得更加难读.不再兼容低版本浏览器,而且看起来更加零散.本次阅读的是Sizzle第一个阶段的最终版本jQuery1.7,从中收获颇多,一方面是框架设计的思路,另外一方面是

jQuery选择器代码详解(一)——Sizzle方法

对jQuery的Sizzle各方法做了深入分析(同时也参考了一些网上资料)后,将结果分享给大家.我将采用连载的方式,对Sizzle使用的一些方法详细解释一下,每篇文章介绍一个方法. 若需要转载,请写明出处,多谢. /* * @param selector 选择器字符串 * @param context 执行匹配的最初的上下文(即DOM元素).若context没有赋值,则取document. * @param results 已匹配出的部分最终结果.若results没有赋值,则赋予空数组. * @

JQuery日期_5.20 JQuery对Sizzle选择器的扩展

代码很简单直接上源码 function winnow( elements, qualifier, not ) { //如果qualifier是函数 if ( jQuery.isFunction( qualifier ) ) { //not为true时,返回qualifier返回false的elements //not为false时,返回qualifier返回true的elements return jQuery.grep( elements, function( elem, i ) { /* j

jquery 1.7.2源码解析(三) 选择器Sizzle

选择器Sizzle 一)Sizzle( selector, context, results, seed ) 该函数用于查找与选择器表达式selector匹配的元素集合,是选择器引擎的入口. var Sizzle = function( selector, context, results, seed ) { selector: CSS选择器表达式 context: DOM元素或者文档对象,作为查找元素的上下文,用于限定查找范围.默认值是当前文档对象. results: 可选的数组或者类数组,把

jQuery选择器代码详解(四)——Expr.preFilter

原创文章,转载请注明出处,多谢! Expr.preFilter是tokenize方法中对ATTR.CHILD.PSEUDO三种选择器进行预处理的方法.具体如下: Expr.preFilter : { "ATTR" : function(match) { /* * 完成如下任务: * 1.属性名称解码 * 2.属性值解码 * 3.若判断符为~=,则在属性值两边加上空格 * 4.返回最终的mtach对象 * * match[1]表示属性名称, * match[1].replace(rune

jQuery选择器代码详解(八)——addCombinator函数

function addCombinator(matcher, combinator, base) 1.源码 function addCombinator(matcher, combinator, base) { var dir = combinator.dir, checkNonElements = base && dir === "parentNode", doneName = done++; return combinator.first ? // Check a

JQuery选择器中含有冒号的ID处理差异的分析

问题提出 对于一个输入框, 如果其id中含有冒号(:),选择器使用需要有特殊写法, 例如 id为下 <input type="text" value="ddd" id="a:b"> 使用$(selector)直接使用#id值, 找不到DOM console.log("#a:b")console.log($("#a:b").length) // output 0 经过探索可以使用以下两个方法选择到

jQuery选择器源码分析和easyui核心分析

写在选择器源码分析之前 这里指对1.7.2版本的源码分析,更高版本添加了更多代码. 整个jQuery的代码是写在一个(function(window, undefined){})(window);这样一个闭包里.请思考,为什么要这样做? 将其写在一个闭包函数里,并传入window直接运行的好处有三: 1,统一命名空间,防止变量的污染:  2,将window作为参数传入函数,在函数里调用window的时候,就不用再去找外层的对象,可以提高效率 : 3,undefined并不是javascript的