jQuery技术内幕:深入解析jQuery架构设计与实现原理. 3.1 总体结构

简介:

3.1 总体结构

Sizzle的总体源码结构如代码清单3-1所示,为了方便解释,代码中增加了注释:

代码清单3-1  Sizzle 的总体源码结构

(function(){

   // 选择器引擎入口,查找与选择器表达式 selector 匹配的元素集合

   var Sizzle = function( selector, context, results, seed )  { ... };

   // 工具方法,排序、去重

   Sizzle.uniqueSort = function( results )  { ... };

   // 便捷方法,使用指定的选择器表达式 expr 对元素集合 set 进行过滤

   Sizzle.matches = function( expr, set )  { ... };

   // 便捷方法,检查某个元素 node 是否匹配选择器表达式 expr

   Sizzle.matchesSelector = function( node, expr )  { ... };

   // 内部方法,对块表达式进行查找

   Sizzle.find = function( expr, context, isXML )  { ... };

   // 内部方法,用块表达式过滤元素集合

   Sizzle.filter = function( expr, set, inplace, not )  { ... };

   // 工具方法,抛出异常

   Sizzle.error = function( msg )  { ... };

   // 工具方法,获取 DOM 元素集合的文本内容

   var getText = Sizzle.getText = function( elem )  { ... };

   // 扩展方法和属性

   var Expr = Sizzle.selectors = {

       // 块表达式查找顺序

       order: [ "ID", "NAME", "TAG" ],

       // 正则表达式集,用于匹配和解析块表达式

       match:  { ID, CLASS, NAME, ATTR, TAG, CHILD, POS, PSEUDO },

       leftMatch:  { ... },

       // 属性名修正函数集

       attrMap: { "class", "for" },

       // 属性值读取函数集

       attrHandle:  { href, type },

       // 块间关系过滤函数集

       relative: { "+", ">", "", "~" },

       // 块表达式查找函数集

       find: { ID, NAME, TAG },

       // 块表达式预过滤函数集

       preFilter: { CLASS, ID, TAG, CHILD, ATTR, PSEUDO, POS },

       // 伪类过滤函数集

       filters: { enabled, disabled, checked, selected, parent, empty, has, header,

       text, radio, checkbox, file, password, submit, image, reset, button, input,

       focus },

       // 位置伪类过滤函数集

       setFilters: { first, last, even, odd, lt, gt, nth, eq },

       // 块表达式过滤函数集

       filter: { PSEUDO, CHILD, ID, TAG, CLASS, ATTR, POS }

   };

 

   // 如果支持方法 querySelectorAll(),则调用该方法查找元素

   if ( document.querySelectorAll ) {

       (function(){

           var oldSizzle = Sizzle;

           Sizzle = function( query, context, extra, seed ) {

               // 尝试调用方法 querySelectorAll() 查找元素

               // 如果上下文是 document,则直接调用 querySelectorAll() 查找元素

               return makeArray( context.querySelectorAll(query), extra );

               // 如果上下文是元素,则为选择器表达式增加上下文,然后调用 querySelectorAll()

               // 查找元素

               return makeArray( context.querySelectorAll( "[id='" + nid + "'] " +

               query ), extra );

               // 如果查找失败,则仍然调用 oldSizzle()

               return oldSizzle(query, context, extra, seed);

           };

       })();

   }

 

   // 如果支持方法 matchesSelector(),则调用该方法检查元素是否匹配选择器表达式

   (function(){

       var matches = html.matchesSelector

                        || html.mozMatchesSelector

                        || html.webkitMatchesSelector

                        || html.msMatchesSelector;

       // 如果支持方法 matchesSelector()

       if ( matches ) {

           Sizzle.matchesSelector = function( node, expr ) {

               // 尝试调用方法 matchesSelector()

               var ret = matches.call( node, expr );

               return ret;

               // 如果查找失败,则仍然调用 Sizzle()

               return Sizzle(expr, null, null, [node]).length > 0;

           };

       }

   })();

 

   // 检测浏览器是否支持 getElementsByClassName()

   (function(){

       Expr.order.splice(1, 0, "CLASS");

       Expr.find.CLASS = function( match, context, isXML )  { ... };

   })();

   // 工具方法,检测元素 a 是否包含元素 b

   Sizzle.contains = function( a, b ) { ... };

})();

代码清单3-1中的变量Expr与Sizzle.selectors指向了同一个对象,这么做是为了减少拼写字符数、缩短作用域链,并且方便压缩。但是为了直观和避免混淆,本章在描述中统一使用Sizzle.selectors。

代码清单3-1中已经介绍了浏览器支持方法querySelectorAll()时的查找过程,本章后面的内容将介绍和分析在不支持的情况下,Sizzle是如何模拟方法querySelectorAll()的行为的。另外,为了简化描述,在后文中把“块表达式查找函数集”“块表达式预过滤函数集”“块表达式过滤函数集”分别简称为“查找函数集”“预过滤函数集”“过滤函数集”。

代码清单3-1中的方法和属性大致可以分为4类:公开方法、内部方法、工具方法、扩展方法及属性。它们之间的调用关系如图3-1所示。

 

图3-1 Sizzle的方法、功能和调用关系

相关文章
|
18天前
|
Linux 编译器 开发者
Linux设备树解析:桥接硬件与操作系统的关键架构
在探索Linux的庞大和复杂世界时🌌,我们经常会遇到许多关键概念和工具🛠️,它们使得Linux成为了一个强大和灵活的操作系统💪。其中,"设备树"(Device Tree)是一个不可或缺的部分🌲,尤其是在嵌入式系统🖥️和多平台硬件支持方面🔌。让我们深入了解Linux设备树是什么,它的起源,以及为什么Linux需要它🌳。
Linux设备树解析:桥接硬件与操作系统的关键架构
|
1月前
|
存储 搜索推荐 数据挖掘
ElasticSearch架构介绍及原理解析
ElasticSearch架构介绍及原理解析
106 0
|
1月前
|
消息中间件 Cloud Native Java
【Spring云原生系列】SpringBoot+Spring Cloud Stream:消息驱动架构(MDA)解析,实现异步处理与解耦合
【Spring云原生系列】SpringBoot+Spring Cloud Stream:消息驱动架构(MDA)解析,实现异步处理与解耦合
|
4天前
|
前端开发 Java
SpringBoot之三层架构的详细解析
SpringBoot之三层架构的详细解析
20 0
|
28天前
|
canal 消息中间件 关系型数据库
【分布式技术专题】「分布式技术架构」MySQL数据同步到Elasticsearch之N种方案解析,实现高效数据同步
【分布式技术专题】「分布式技术架构」MySQL数据同步到Elasticsearch之N种方案解析,实现高效数据同步
78 0
|
1月前
|
运维 Linux Apache
LAMP架构调优(十)——Apache禁止指定目录PHP解析与错误页面优化
LAMP架构调优(十)——Apache禁止指定目录PHP解析与错误页面优化
199 2
|
1月前
|
消息中间件 弹性计算 Kubernetes
Knative 架构解析
【2月更文挑战第29天】Knative作为构建无服务器产品的基础设施,建立在Kubernetes和Istio之上,提供从源代码到服务的编排、流量管理、自动扩缩容和事件绑定等功能,分为Build、Eventing和Serving三个模块,旨在确保编程模型的可移植性。
|
1月前
|
设计模式 存储 API
C++桥接模式大解析:轻松设计与实现高效软件架构
C++桥接模式大解析:轻松设计与实现高效软件架构
161 0
|
1月前
|
消息中间件 存储 Cloud Native
深度剖析 RocketMQ 5.0,架构解析:云原生架构如何支撑多元化场景?
了解 RocketMQ 5.0 的核心概念和架构概览;然后我们会从集群角度出发,从宏观视角学习 RocketMQ 的管控链路、数据链路、客户端和服务端如何交互;学习 RocketMQ 如何实现数据的存储,数据的高可用,如何利用云原生存储进一步提升竞争力。
140056 2
|
1月前
|
SQL API 数据处理
新一代实时数据集成框架 Flink CDC 3.0 —— 核心技术架构解析
本文整理自阿里云开源大数据平台吕宴全关于新一代实时数据集成框架 Flink CDC 3.0 的核心技术架构解析。
729 0
新一代实时数据集成框架 Flink CDC 3.0 —— 核心技术架构解析

推荐镜像

更多