jQuery源码分析-04选择器-Sizzle-工作原理分析
作者:手浪用户2502876054 | 来源:互联网 | 2022-10-13 17:23
在分析Sizzle源码之前,先整理一下选择器的工作原理,先明确一些选择器中用到的名词,后边阅读时不会有歧义
作者:nuysoft/高云 QQ:47214707 EMail:nuysoft@gmail.com 声明:本文为原创文章,如需转载,请注明来源并保留原文链接。 在分析Sizzle源码之前,先整理一下选择器的工作原理 先明确一些选择器中用到的名词,后边阅读时不会有歧义: 选择器表达式: "div > p" 块表达式: "div" "p" 并列选择器表达式: "div, p" 块分割器: Sizzle中的chunker正则,对选择器表达式从左向右分割出一个个块表达式 查找器: 对块表达式进行查找,找到的DOM元素数组叫候选集 过滤器: 对块表达式和候选集进行过滤 关系过滤器 对块表达式之间的关系进行过滤,共有四种关系:"+" 紧挨着的兄弟关系;">" 父子关系;"" 祖先关系;"~" 之后的所有兄弟关系 候选集: 查找器的结果,待过滤器进行过滤 映射集: 候选集的副本,过滤器和关系过滤器对映射集进行过滤 工作流程: 1. 使用块分割器对选择器表达式进行分割,从左向右 如果遇到用逗号","分割的并列选择器表达式,只分割至第一个逗号前边的选择器表达式1,将剩余部分记录下来 2. 对最后一个块表达式进行查找Sizzle.find,结果放入候选集set,并将块表达式中匹配的字符串部分删除 查找器Sizzle.find从正则集Expr.match获取对应的正则表达式,对块表达式进行匹配,匹配成功则从查找函数集Expr.find获取对应的查找函数执行 查找顺序定义在Expr.order中,依次是:ID CLASS NAME TAG,查找时CLASS需要浏览器支持getElementsByClassName Expr.match中设定了ID CLASS NAME ATTR TAG CHILD POS PSEUDO的正则匹配表达式 3. 如果最后一个块表达式不为空(字符串),过滤器Sizzle.filter对set进行过滤 过滤器Sizzle.filter仅对单个块表达式起作用,仅对候选集set中的元素起作用,检查候选集set中的元素满足剩余的块表达式 在过滤器Sizzle.filter的过滤过程中,不符合条件的被设置为false,符合条件的不做修改 过滤时从正则集Expr.leftMatch获取对应的正则表达式,对块表达式进行匹配,匹配成功则从Expr.filter获取对应的过滤函数执行 Expr.leftMatch定义了与Expr.match同样数量的正则表达式:ID CLASS NAME ATTR TAG CHILD POS PSEUDO 过滤函数集Expr.filter定义了PSEUDO CHILD ID TAG CLASS ATTR POS的过滤函数 过滤器Sizzle.filter进行过滤之前,会先调用预过滤器Expr.preFilter对过滤所需的参数进行修正,但是CLASS是个例外 在CLASS进行预过滤时做了优化,直接将匹配class的元素作为候选集返回,缩小过滤范围,缩小候选集范围 将以上查找和过滤得到候选集set复制,放入映射集checkSet,后边的过滤操作在checkSet上进行 对最后一个块表达式的查找和过滤到这里结束,得到一个候选集set和映射集checkSet 4. 在映射集checkSet上将剩余的块表达式从右向左进行过滤,根据与前一个块表达式的关系,从关系过滤器集Expr.relative中获取对应的函数执行关系过滤 在关系过滤器Expr.relative的过滤过程中,不符合条件的被设置为false,符合条件的则被设置为父元素、祖先元素、兄长元素 元素之间的关系共有四种:"+" 紧挨着的兄弟关系;">" 父子关系;"" 祖先关系;"~" 之后的所有兄弟关系 在关系过滤器Expr.relative的过滤过程中,如果遇到块表达式是标签TAG的情况,则直接比较标签类型nodeName是否相等 如果不是标签TAG的情况,则会调用过滤器Sizzle.filter进行过滤,过滤过程见第3步 从右向左过滤,直到所有块表达式全部过滤完 5. 根据过滤后的映射集checkSet,从候选集set中挑选最终的结果集,在映射集checkSet中 如果是null、false,将被过滤 如果不是Element(nodeType===1),将被过滤 如果上下文不是Document而是某个Element,不是Element的子元素的,将被过滤 6. 如果存在并列表达式,重复1~5,并将得到的最终结果集合并、排序、去重 如果仅有一个选择器表达式,没有并列选择器表达式,不需要排序 以下过程不属于Sizzle,属于jQuery对Sizzle的扩展 7. 如果存在多个上下文,对每个上下文重复1~6 多个上下文例子:$('div').find('div > p'),$('div')可能找到多个div 其实第7步是jQuery选择器的入口,从第7步去调用1~6,调用时传入一个空的jQuery对象作为结果集 默认以document为上下文:(context || rootjQuery).find( selector ) 8. 将从多个上下文找到的结果集合并、去重,返回结果集 done!
推荐阅读
本文详细介绍了 Java 网站开发的相关资源和步骤,包括常用网站、开发环境和框架选择。 ...
[详细]
蜡笔小新 2024-11-14 22:39:58
大家好,我是归辰。秋招结束后,我已顺利入职,并应公子龙的邀请,分享一些秋招面试的心得体会,希望能帮助到学弟学妹们,让他们在未来的面试中更加顺利。 ...
[详细]
蜡笔小新 2024-11-13 18:41:58
本文介绍了如何使用Visual Studio Code、Sublime Text等编辑器批量删除MATLAB代码中的注释和空行,同时提供了一些高级技巧以确保代码的整洁。 ...
[详细]
蜡笔小新 2024-11-13 11:13:30
本文介绍了在 MySQL 中如何使用正则表达式来提高查询效率,通过具体示例展示了如何筛选包含中文字符的记录,并详细解释了正则表达式的各种特殊字符和结构。 ...
[详细]
蜡笔小新 2024-11-12 21:03:49
本文记录了 JavaScript 中正则表达式的使用方法和常见操作,包括匹配、替换、搜索等。 ...
[详细]
蜡笔小新 2024-11-12 11:48:21
本文探讨了Oracle提供的免费工具DBSAT,该工具能够有效协助用户检测和优化数据库配置的安全性。通过全面的分析和报告,DBSAT帮助用户识别潜在的安全漏洞,并提供针对性的改进建议,确保数据库系统的稳定性和安全性。 ...
[详细]
蜡笔小新 2024-11-11 14:44:47
该大学网站采用PHP和MySQL技术,在校内可免费访问某些外部收费资料数据库。为了方便学生校外访问,建议通过学校账号登录实现免费访问。具体方案可包括利用学校服务器作为代理,结合身份验证机制,确保合法用户在校外也能享受免费资源。 ...
[详细]
蜡笔小新 2024-11-10 03:11:33
在ElasticStack日志监控系统中,Logstash编码插件自5.0版本起进行了重大改进。插件被独立拆分为gem包,每个插件可以单独进行更新和维护,无需依赖Logstash的整体升级。这不仅提高了系统的灵活性和可维护性,还简化了插件的管理和部署过程。本文将详细介绍这些编码插件的功能、配置方法,并通过实际生产环境中的应用案例,展示其在日志处理和监控中的高效性和可靠性。 ...
[详细]
蜡笔小新 2024-11-09 19:27:28
第一章介绍了统计学习方法的基础概念与理论框架。1.2节详细讨论了两种模型类型:一种直接输出具体的数值结果,另一种则输出概率分布。条件概率分布描述了在给定输入 \( x \) 的情况下,多个可能输出 \( y \) 的概率分布情况,而直接输出数值的模型则为每个输入 \( x \) 提供一个确定的输出值。这一部分还探讨了这些模型在实际应用中的重要性和应用场景。 ...
[详细]
蜡笔小新 2024-11-09 13:15:04
在日常开发中,正则表达式是处理字符串时不可或缺的工具。本文汇总了常用的正则表达式,帮助开发者高效解决常见问题。例如,验证数字:`1$`;验证n位数字:`^\d{n}$`;验证至少n位数字:`^\d{n,}$`;验证m到n位数字:`^\d{m,n}$`。此外,还涵盖了验证零和非零数字、邮箱地址、手机号码等多种场景,建议关注并收藏以备不时之需。 ...
[详细]
蜡笔小新 2024-11-08 16:38:13
在Python中,字符串是编程中最基本且常用的数据类型之一。尽管许多初学者是从C语言开始接触字符串,通常通过经典的“Hello, World!”程序入门,但Python对字符串的处理方式更为灵活和强大。本文将深入探讨Python中的字符串处理机制,包括字符串的创建、操作、格式化以及编码解码等方面,帮助读者全面理解Python字符串的特性和应用。 ...
[详细]
蜡笔小新 2024-11-08 05:02:14
本文探讨了在Python中使用序列号字符串进行高效模式替换的方法。具体而言,通过将HTML标签中的`&`替换为`{n}`,并生成形如`[tag, {n}]`的哈希原始字符串。示例字符串为:“这是一个字符串。这是另一部分。”该方法能够有效提升替换操作的性能和可读性。 ...
[详细]
蜡笔小新 2024-11-07 19:42:59
正则表达式是一种强大的文本处理工具,通过特定的字符序列来定义搜索模式。本文详细介绍了Python内置的`re`模块,探讨了其在字符串匹配、验证和提取中的应用。例如,可以通过正则表达式验证电子邮件地址、电话号码、QQ号、密码、URL和IP地址等。此外,文章还深入解析了`re`模块的各种函数和方法,提供了丰富的示例代码,帮助读者更好地理解和使用这一工具。 ...
[详细]
蜡笔小新 2024-11-07 17:25:01
在探讨 MySQL 正则表达式 REGEXP 的功能与应用之前,我们先通过一个小实验来对比 REGEXP 和 LIKE 的性能。通过具体的代码示例,我们将评估这两种查询方式的效率,以确定 REGEXP 是否值得深入研究。实验结果将为后续的详细解析提供基础。 ...
[详细]
蜡笔小新 2024-11-07 16:02:12
在 Python 中,可以通过正则表达式来实现去除字符串中的非中文字符。具体方法是使用 `re` 模块中的 `re.sub()` 函数,配合正则表达式 `[^u4e00-u9fa5]` 来匹配并替换掉所有非中文字符,从而保留字符串中的中文部分。这种方法简洁高效,适用于多种文本处理场景。 ...
[详细]
蜡笔小新 2024-11-07 15:30:50
手浪用户2502876054
这个家伙很懒,什么也没留下!