`
暴走的酱油瓶
  • 浏览: 10758 次
  • 性别: Icon_minigender_1
  • 来自: 酱油厂
社区版块
存档分类
最新评论

Js杂记-2

 
阅读更多
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 );
}
分享到:
评论

相关推荐

    网络问题:收集平时遇到的问题

    前端点滴记录学习中遇到的问题,记录成长杂记-48-简介:设置定时任务为每天凌晨2点执行和每小时执行一次?作者:hazer,时间:2019-6-28杂记-47-杂记-46-杂记-45-杂记-44-杂记-35- 内置简介:github readme自动生成...

    TrackLastFMForMe:跟踪 LastFM 杂记到 TrackThisForMe

    跟踪 LastFM 杂记到 TrackThisForMe 根本无法正常使用。 需要(目前)相当多的配置来设置。 如何使用 在 main.js 中填写选项 var options { trackthisforme: { access_token: '', category_id: 0 }, ...

    杂记

    杂记 数据库(PostgreSql,MySql) Unix服务 Unix工具 Linux 配置_管理_系统 Криптография 开发运维 Курсы

    kaki-note-02:七瀑布八醒杂记博客

    Netlify开发设定Base directory: Not setBuild command: yarn buildPublish directory: public/Builds: Active本地开发人员yarn installyarn dev执照该项目是根据条款获得。

    asp.net知识库

    第2章 并发操作的一致性问题 (2) Using sqlite with .NET Visual Studio 2005 中的新 DataSet 特性 MySQL 和 .Net2.0配合使用 与DotNet数据对象结合的自定义数据对象设计 (二) 数据集合与DataTable 与DotNet数据对象...

    miniprogramThreeDynamic.zip

    微信小程序加载glb外部模型,并且进行平移旋转操作

    【uni-app】只支持在微信小程序运行的 导入外部3d模型

    博客描述:https://blog.csdn.net/qq_40558766/article/details/127109617?spm=1001.2014.3001.5502

    matlab有什么好玩的代码-Blogs:记录一些学习历程与思考的blogs

    matlab有什么好玩的代码 title date categories tags README 2019-11-12 14:39:57 -0800 Blogs 今天(10/21/2017)突然发现我的github不能这样子用,我完全把这玩意儿当成博客网站了,代码...这里是一些杂记:) Matlab 这

    PersonalBlog:Nealyang个人博客

    随笔、总结、个人、学习、杂记 任何问题交流,提issue 搞搞js Typescript Typescript+Decorator:装饰你的代码 【THE LAST TIME】Typescript 进阶之重难点梳理 一张页面引起的前端架构思考 拍卖源码架构在拍品详情页...

    Miscellanea:不同的东西

    杂记不同的东西多维数据集需要three.js

    GlitterAndRetribution

    杂记 网站 领英 运球 推特 执照 用户故事,MVP,规范和伪代码 humans.txt 安装 包装控制(推荐) 在制品:尚未提交给PackageControl.io 。 手动的 在制品:包括手动安装说明 设置 打开用户首选项文件,可以...

    markdown:前端学习笔记

    前端杂记 策略模式 发布订阅者模式 责任链模式(todo) 0.1+0.2 为什么不等于 0.3 == 和 === 的区别 ... 浏览器 HTTP 的缓存机制 Event Loop 预编译 进阶 前端性能初探-h5 工作笔记 百度地图换高德地图中遇到的坑 ...

    信息技术挑战:信息技术的挑战问题

    杂记 这花了多长时间? 是的,我花的时间超过了估计的时间。 部分原因是我将其视为尝试使用grid的机会,而我从来没有机会在此级别上使用过。 而且,我通常没有时间去真正地探讨有关语义选择的琐事。 另一部分是我...

    Miscellany:各种与项目无关的一次性,测试和转移

    杂记当前内容: Domino StateManager:一个包含StateManager实现的数据库,该实现将视图状态写入到随附的NSF而不是文件系统中frostillicus.wrapbootstrap.ace_1.3:用于 。 请注意,实际主题不包括在内-其js,css等...

    BLOG:LinYY博客

    林一一同学的杂记 今年春天的太阳一定很暖. /hero.jpg height color 920px wheat false Guide /views/other/guide title details Yesterday 开发一款看着开心、写着顺手的 vuepress 博客主题 title details Today ...

    jchans.github.io:jchans的github页面

    老翰的Github Page的回购 有点像是放笔记或杂记的地方,有点杂。 希望能慢慢整理成某种部落格的型态。 这个Github页面: :

    miniprogramThree.zip

    Three.js 加载3d模型 (修改版)修改真机背景可透明

    demoTest.zip

    uni-app 的 APP 端导入外部 3d 模型

Global site tag (gtag.js) - Google Analytics