1、sizzle在document.querySelectorAll可以使用情况下,如果context是document优先使用querySelectorAll查询
Sizzle = function(query, context, extra, seed){
context = context || document;
if ( !seed && context.nodeType === 9 && !Sizzle.isXML(context) ) {
try {
return makeArray( context.querySelectorAll(query), extra );
} catch(e){}
}
return oldSizzle(query, context, extra, seed);
};
2、否则根据正则,拆分选择器,存入parts
do {
// chunker的lastIndex归0
chunker.exec("");
m = chunker.exec(soFar);
if ( m ) {
//每次重新赋值匹配右半部分
soFar = m[3];
//从左依次存入数组
parts.push( m[1] );
//当有“,”时,代表并列关系,额外标示,退出循环
if ( m[2] ) {
extra = m[3];
break;
}
}
} while ( m );
3.1、parts长度大于1且匹配POS正则的选择器,进人下面分支。
POS的正则(/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/)
为了方便理解举个例子,例如“p:first + span:first”
//sizzle多次调用时,结合当前的context快速定位,条件是“+”、“>”、“”、“~”中一个
//拿例子来说,再次sizzle,到此就是直接调用posProcess函数,选择器是+span:first,而context是已经找到的[p]
if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
set = posProcess( parts[0] + parts[1], context );
} else {
//拿例子说就是先根据context,查找p:first
set = Expr.relative[ parts[0] ] ?
[ context ] :
Sizzle( parts.shift(), context );
//拿例子说就是依次去处理后面的+span:first
while ( parts.length ) {
selector = parts.shift();
if ( Expr.relative[ selector ] ) {
selector += parts.shift();
}
set = posProcess( selector, set );
}
}
下面来看看posProcess函数
var posProcess = function(selector, context){
var tmpSet = [], later = "", match,
root = context.nodeType ? [context] : context;
// 拿例子说,先把:first之类替换掉,找当前context下的span,存入tmpSet
//同时把:first之类的存入later保存
while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
later += match[0];
selector = selector.replace( Expr.match.PSEUDO, "" );
}
selector = Expr.relative[selector] ? selector + "*" : selector;
for ( var i = 0, l = root.length; i < l; i++ ) {
Sizzle( selector, root[i], tmpSet );
}
return Sizzle.filter( later, tmpSet );
};
把剩下判断交由Sizzle.filter去验证,最后给出结果,filter比较长,就不贴了,直接看源码吧。
3.2看看另一个分支。
先是一个优先匹配的原则,找到后更新当前的context
if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
ret = Sizzle.find( parts.shift(), context, contextXML );
context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
}
继续
if ( context ) {
//在此可以看出Sizzle是从右到左的寻找
ret = seed ?
{ expr: parts.pop(), set: makeArray(seed) } :
Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
//找出匹配的集合
set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
if ( parts.length > 0 ) {
checkSet = makeArray(set);
} else {
prune = false;
}
//依次遍历匹配
while ( parts.length ) {
cur = parts.pop();
pop = cur;
if ( !Expr.relative[ cur ] ) {
cur = "";
} else {
pop = parts.pop();
}
if ( pop == null ) {
pop = context;
}
Expr.relative[ cur ]( checkSet, pop, contextXML );
}
} else {
checkSet = parts = [];
}
有些情况不准,需求再过滤次
if ( toString.call(checkSet) === "[object Array]" ) {
if ( !prune ) {
results.push.apply( results, checkSet );
}
//context存在时,存在cotext和parentNode混判情况,需要再判断次
else if ( context && context.nodeType === 1 ) {
for ( i = 0; checkSet[i] != null; i++ ) {
if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
results.push( set[i] );
}
}
} else {
for ( i = 0; checkSet[i] != null; i++ ) {
if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
results.push( set[i] );
}
}
}
} else {
makeArray( checkSet, results );
}
处理并列关系的选择器,要排重
if ( extra ) {
Sizzle( extra, origContext, results, seed );
Sizzle.uniqueSort( results );
}
分享到:
相关推荐
Vue.js 是一款轻量级的前端JavaScript框架,由尤雨溪开发并维护,因其易学易用、组件化开发和高性能的特点,在Web开发领域中广受欢迎。本资源包中的"Vue-dev-note-master1"可能包含了关于Vue开发的笔记、教程、示例...
前端点滴记录学习中遇到的问题,记录成长杂记-48-简介:设置定时任务为每天凌晨2点执行和每小时执行一次?作者:hazer,时间:2019-6-28杂记-47-杂记-46-杂记-45-杂记-44-杂记-35- 内置简介:github readme自动生成...
JS语法结构杂记 JavaScript的语法允许一定程度的灵活性,例如分号的使用并非强制要求。 - **分号的可选性** - 在JavaScript中,当语句写在新的一行时,分号通常是可选的。这是因为解析器会自动插入分号(ASI, ...
该项目是一个基于HTML语言的Linux知识杂记文档设计源码,共包含39个文件,涵盖33个reStructuredText和Markdown文档、1个许可协议、1个HTML页面、1个JavaScript脚本、1个Python脚本以及2个Markdown文件。内容主要包括...
### QML杂记 Qt_Quick中文手册精要 #### 一、引言 QML(Qt Markup Language)是一种声明式的编程语言,专为Qt框架设计,用于构建动态且丰富的用户界面。Qt Quick作为Qt框架的一个核心组成部分,提供了一系列高级的...
移除HTML中的`required`属性,并将验证规则移到JavaScript部分,可以避免默认错误提示的出现。 其次,处理级联提交表单验证的情况。在某些场景下,我们需要在提交表单前验证多个独立的子表单。Element-UI的`...
本文将深入探讨Oracle 9i的一些关键知识点,同时结合JavaScript和SQL这两个标签,讨论它们在数据库应用中的角色。 一、Oracle 9i的新特性 1. **Real Application Clusters (RAC)**: Oracle 9i首次引入了RAC技术,...
【标题】:“杂记”涉及了多个IT领域的知识点,包括数据库、Unix服务、Unix工具、Linux系统管理和配置、密码学以及开发运维。 【数据库】:PostgreSQL和MySQL是两种广泛使用的开源关系型数据库管理系统(RDBMS)。...
跟踪 LastFM 杂记到 TrackThisForMe 根本无法正常使用。 需要(目前)相当多的配置来设置。 如何使用 在 main.js 中填写选项 var options { trackthisforme: { access_token: '', category_id: 0 }, ...
Netlify开发设定Base directory: Not setBuild command: yarn buildPublish directory: public/Builds: Active本地开发人员yarn installyarn dev执照该项目是根据条款获得。
ES6,全称ECMAScript 6,是JavaScript语言的一个重要版本更新,引入了许多新的语法特性和功能。本文主要探讨的是ES6中的解构、块级作用域、变量提升、函数声明及其相关特性。 首先,解构是ES6提供的一种方便的数据...
这通常需要借助于JavaScript库three.js来实现,因为three.js是WebGL的一个强大框架,特别适合处理3D图形渲染。 首先,让我们深入了解uni-app。uni-app由ECharts团队开发,基于Vue.js,提供了一套统一的API,用于...
在“Docs:关于所有事物的杂记”这个压缩包中,我们可以期待找到一系列与软件开发、IT基础架构和数据科学相关的个人笔记。这些笔记可能是作者在长期的学习和实践中积累的知识结晶,涵盖了广泛的IT主题,旨在帮助读者...
2. **模型转换**:使用如Blender或Autodesk Maya等专业3D建模软件,或者在线工具将原始3D模型(如OBJ、3DS等)转换为glTF或FBX。 3. **加载模型**:在uni-app中,利用微信小程序提供的API,例如通过`wx.request()`...
用户可以在GitHub仓库中创建一个名为用户名.github.io的仓库,然后将HTML、CSS和JavaScript等文件上传,GitHub会自动将这个仓库的内容发布为一个网站。 【GitHub仓库】 "baqianxin.github.io-master" 这个文件名...
jQuery与Rails的集成允许开发者使用熟悉的链式方法和简化的API来编写JavaScript代码。 2. **Ruby代码小计**:这里可能涵盖了Ruby编程的基础和进阶技巧,如变量、数据类型、控制流、方法定义以及面向对象特性,如...
2. **three.js**: three.js是基于WebGL的3D库,它简化了WebGL编程,提供了丰富的3D对象、光照、材质、动画等功能。在这个项目中,three.js用于加载和显示3D模型,以及处理模型的平移、旋转等交互操作。 3. **Glb...
matlab有什么好玩的代码 title date categories tags README 2019-11-12 14:39:57 -0800 Blogs 今天(10/21/2017)突然发现我的github不能这样子用,我完全把这玩意儿当成博客网站了,代码...这里是一些杂记:) Matlab 这
2. JavaScript文件:可能包含使用three.js库的代码,用于处理和显示多维数据。 3. HTML文件:可能包含用于展示和交互的页面结构,与CSS和JavaScript协同工作。 4. 数据文件:可能是JSON或其他格式的文件,存储了多维...