博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JS框架设计读书笔记之-选择器引擎02
阅读量:5280 次
发布时间:2019-06-14

本文共 1844 字,大约阅读时间需要 6 分钟。

选择器引擎涉及相关概念

   

 

  概念

 

  以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行都有涉及,就不贴出来了。

转载于:https://www.cnblogs.com/QH-Jimmy/p/6437986.html

你可能感兴趣的文章
Hadoop.2.x_伪分布环境搭建
查看>>
数位dp的简单模板
查看>>
Android fragment 回调函数改进
查看>>
去除swagger ui的红色 error 错误提示
查看>>
事件绑定、解除和监听
查看>>
ArcGIS JS 学习笔记1 用ArcGIS JS 实现仿百度地图的距离量测和面积量测
查看>>
在Windows Server 2012上安装SharePoint 2013
查看>>
C++的IO处理中的头文件以及类理解(2)<sstream>头文件
查看>>
连引用都答不上,凭什么说你是Java服务端开发
查看>>
Android子线程更新UI的方法总结
查看>>
WPF 数据绑定基础
查看>>
AndroidStudio 编译异常java.lang.OutOfMemoryError: GC overhead limit exceeded
查看>>
Web分布式架构演变过程
查看>>
一份“奇妙”的银行流水
查看>>
mysql数据库指定ip远程访问
查看>>
对ASP.NET MVC项目中的视图做单元测试
查看>>
ios app提交之前需要哪几个证书
查看>>
php一些常用功能封装
查看>>
java_MD5加密
查看>>
排序算法
查看>>