章节
问答
课签
笔记
评论
占位
占位

Sizzle超级匹配器(中)

matcher就是elementMatcher函数的包装,整个匹配的核心就在这个里面了:

function( elem, context, xml ) {
    var i = matchers.length;
    while ( i-- ) {
        if ( !matchers[i]( elem, context, xml ) ) {
            return false;
        }
    }
    return true;
} 

我们先来回顾下这个matchers的组合原理,这个地方是最绕的,也是最晕的,所以还是要深入的理解才行哦。

先上个简单的流程图:

执行分解:

第一步:

div > p + div.aaron input[type="checkbox"]

从右边剥离出原生API能使用的接口属性

context.getElementsByTagName( input )

所以找到了input,因为只可以用tag是查询,但是此时结果是个合集,引入seed的概念,称之为种子合集。

第二步:

div > p + div.aaron [type="checkbox"]

重组选择器,踢掉input,得到新的tokens词法元素哈希表。

第三步:

通过matcherFromTokens函数,然后根据关系选择器 【">","空","~","+"】拆分分组,因为DOM中的节点都是存在关系的,所以引入Expr.relative -> first:true 两个关系的“紧密”程度,用于组合最佳的筛选。

一次按照如下顺序解析并且编译闭包函数,编译规则:div > p + div.aaron [type="checkbox"]。

编译成4组闭包函数,然后在前后在合并组合成一组:

div >
p +
div.aaron 
input[type="checkbox"]

先看构造一组编译函数

  A: 抽出div元素,对应的是TAG类型
  B: 通过Expr.filter找到对应匹配的处理器,返回一个闭包处理器

如TAG方法:

"TAG": function( nodeNameSelector ) {
    var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
    return nodeNameSelector === "*" ?
        function() { return true; } :
        function( elem ) {
            return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
        };
},

  C:将返回的curry方法放入到matchers匹配器组中,继续分解

  D:抽出子元素选择器 '>' ,对应的类型 type: ">" 

  E:通过Expr.relative找到elementMatcher方法分组合并多个词素的的编译函数

function(elem, context, xml) {
   var i = matchers.length;
   while (i--) {
       if (!matchers[i](elem, context, xml)) {
           return false;
       }
   }

所以这里其实就是执行了各自Expr.filter匹配中的的判断方法了,看到这里matcher方法原来运行的结果都是bool值,所以这里只返回了一个组合闭包,通过这个筛选闭包,各自处理自己内部的元素。

F:返回的这个匹配器还是不够的,因为没有规范搜索范围的优先级,所以这时候还要引入addCombinator方法

G:根据Expr.relative -> first:true 两个关系的“紧密”程度

如果是亲密关系addCombinator返回:

function( elem, context, xml ) {
    while ( (elem = elem[ dir ]) ) {
        if ( elem.nodeType === 1 || checkNonElements ) {
            return matcher( elem, context, xml );
        }
    }
}

所以可见如果是紧密关系的位置词素,找到第一个亲密的节点,立马就用终极匹配器判断这个节点是否符合前面的规则。

任务

?不会了怎么办
||

提问题

写笔记

公开笔记
提交
||

请验证,完成请求

由于请求次数过多,请先验证,完成再次请求

加群二维码

打开微信扫码自动绑定

您还未绑定服务号

绑定后可得到

  • · 粉丝专属优惠福利
  • · 大咖直播交流干货
  • · 课程更新,问题答复提醒
  • · 账号支付安全提醒

收藏课程后,能更快找到我哦~

使用 Ctrl+D 可将课程添加到书签

邀请您关注公众号
关注后,及时获悉本课程动态

举报

0/150
提交
取消
全部 精华 我要发布
全部 我要发布
最热 最新
只看我的

手记推荐

更多

本次提问将花费2个积分

你的积分不足,无法发表

为什么扣积分?

本次提问将花费2个积分

继续发表请点击 "确定"

为什么扣积分?