• JS框架设计读书笔记之-选择器引擎02


    选择器引擎涉及相关概念

       

      概念

      以Sizzle的主函数声明为例,来说明引擎的相关概念。

        function Sizzle(selector, context, results, seed) {
            //...
        }

      种子集seed:如果CSS选择器非常复杂,需要分几步来得到结果,那么第一次得到的元素集合就叫种子集。Sizzle引擎的解析基本上是由右到左,种子集中的一部分就是我们最后得到的元素。如果引擎是由左到右,那么就只是依次查询兄弟与子节点。

      结果集results:选择器引擎最终返回的元素集合,约定要与querySelectorAll得到的一致,没有重复元素且要与DOM树上出现的顺序一致。

      过滤集:选取一组元素后,之后每一步骤要处理的元素集合都可以称为过滤集。比如p.aaa,假设浏览器不支持querySelectorAll,那么就只能通过getElementByClassName获取到.aaa,然后循环判断tagName === 'p'进行过滤。若不支持ClassName,只能通过getElementsByTagName得到种子集,然后通过className进行过滤。显示,前面的方法比较快,因为class肯定少;同理,如果是ID的话就更简单了,因为ID只有一个,所以查找更快。Sizzle中,若不支持高级查询querySelectorAll,会以ID、Class、Tag的顺序查找。

      选择器群组:一个选择符被并联选择器','划分成多个组。

      选择器组:选择器群组被关系选择器划分的第一个分组。

      判断函数

      isXML:XML与HTML文档有很大的差异,没有ClassName、getElementById,并且nodeName区分大小写。

      作者给出了一个相对严谨的判断函数:

        function isXML(doc) {
            return doc.createElement('p').nodeName !== doc.createElement('p').nodeName;
        }

      contains:判断参数1是否包含参数2,原为IE的私有实现,后来其他浏览器也借鉴了这个方法。

      compareDocumentPosition:判断两个节点的关系,假设A.compareDocumentPosition(B),结果如下图

      Bits    
    000000 0 元素一致
    000001 1 节点在不同文档
    000010 2 节点B在A之前
    000100 4 节点A在B之前
    001000 8 节点B包含A
    010000 16 节点A包含B
    100000 32 浏览器私有使用

      

     

      有时候,两个元素关系可能满足两个情况,比如A既包含B,又在B之前,会得到20。

      sourceIndex:旧版本IE不支持compareDocumentPosition,于是jQuery用另外一个IE私有方法实现,该方法会根据元素位置从上到下,从左到右依次+1,比如HTML=0,head=1,body=2...如果元素不在DOM,返回-1。

      节点排序去重

      

     

      切割器

      

      如果选择器字符串过长,包含类、ID、TAG等,需要一个正则来进行切割,比如'.class,div a,span'需要切割成['.class',',','div',' ','a',',','body'],然后根据符号依次进行操作,上下文默认指定为document,发现第一个是类选择器,就调用getElementByClassName;然后碰到并联选择器,将上面的元素放入结果集。接着是标签选择器,调用getElementByTagName。然后碰到后代选择器,这里可以先查看下一个选择器群组是什么,发现是a标签,继续调用getElementByTagName,然后对两个进行过滤。接下来碰到并联选择器,重复上面操作。

      但是对于:nth-child(n+1)、.td[attr^='abc']这种复杂的选择符,需要更先进的切割器。

      其实,一个正则切割机已经无法满足要求,Sizzle中应用了大量正则和Expr预解析函数进行字符串切割,代码非常长,Sizzle大概从800行-2800行都有涉及,就不贴出来了。

    老子要日穿V8引擎
  • 相关阅读:
    Lucene
    SQL优化以及索引
    Mysql优化
    RocketMQ
    RocketMQ
    Session共享
    Linux安装Nginx
    初识nginx
    跨域,防止表单重复提交
    HttpClient案例
  • 原文地址:https://www.cnblogs.com/QH-Jimmy/p/6437986.html
Copyright © 2020-2023  润新知