`
暴走的酱油瓶
  • 浏览: 11225 次
  • 性别: 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 );
}
分享到:
评论

相关推荐

    Vue开发资源:vue相关的开发杂记-前端开发

    Vue.js 是一款轻量级的前端JavaScript框架,由尤雨溪开发并维护,因其易学易用、组件化开发和高性能的特点,在Web开发领域中广受欢迎。本资源包中的"Vue-dev-note-master1"可能包含了关于Vue开发的笔记、教程、示例...

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

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

    JS笔记-By Ly.md

    JS语法结构杂记 JavaScript的语法允许一定程度的灵活性,例如分号的使用并非强制要求。 - **分号的可选性** - 在JavaScript中,当语句写在新的一行时,分号通常是可选的。这是因为解析器会自动插入分号(ASI, ...

    基于Html语言的Linux知识杂记文档设计源码

    该项目是一个基于HTML语言的Linux知识杂记文档设计源码,共包含39个文件,涵盖33个reStructuredText和Markdown文档、1个许可协议、1个HTML页面、1个JavaScript脚本、1个Python脚本以及2个Markdown文件。内容主要包括...

    qml杂记 Qt_Quick中文手册.pdf

    ### QML杂记 Qt_Quick中文手册精要 #### 一、引言 QML(Qt Markup Language)是一种声明式的编程语言,专为Qt框架设计,用于构建动态且丰富的用户界面。Qt Quick作为Qt框架的一个核心组成部分,提供了一系列高级的...

    详解element-ui中form验证杂记

    移除HTML中的`required`属性,并将验证规则移到JavaScript部分,可以避免默认错误提示的出现。 其次,处理级联提交表单验证的情况。在某些场景下,我们需要在提交表单前验证多个独立的子表单。Element-UI的`...

    oracle 9i杂记

    本文将深入探讨Oracle 9i的一些关键知识点,同时结合JavaScript和SQL这两个标签,讨论它们在数据库应用中的角色。 一、Oracle 9i的新特性 1. **Real Application Clusters (RAC)**: Oracle 9i首次引入了RAC技术,...

    杂记

    【标题】:“杂记”涉及了多个IT领域的知识点,包括数据库、Unix服务、Unix工具、Linux系统管理和配置、密码学以及开发运维。 【数据库】:PostgreSQL和MySQL是两种广泛使用的开源关系型数据库管理系统(RDBMS)。...

    TrackLastFMForMe:跟踪 LastFM 杂记到 TrackThisForMe

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

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

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

    es6 杂记 (解构)

    ES6,全称ECMAScript 6,是JavaScript语言的一个重要版本更新,引入了许多新的语法特性和功能。本文主要探讨的是ES6中的解构、块级作用域、变量提升、函数声明及其相关特性。 首先,解构是ES6提供的一种方便的数据...

    demoTest.zip

    这通常需要借助于JavaScript库three.js来实现,因为three.js是WebGL的一个强大框架,特别适合处理3D图形渲染。 首先,让我们深入了解uni-app。uni-app由ECharts团队开发,基于Vue.js,提供了一套统一的API,用于...

    Docs:关于所有事物的杂记

    在“Docs:关于所有事物的杂记”这个压缩包中,我们可以期待找到一系列与软件开发、IT基础架构和数据科学相关的个人笔记。这些笔记可能是作者在长期的学习和实践中积累的知识结晶,涵盖了广泛的IT主题,旨在帮助读者...

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

    2. **模型转换**:使用如Blender或Autodesk Maya等专业3D建模软件,或者在线工具将原始3D模型(如OBJ、3DS等)转换为glTF或FBX。 3. **加载模型**:在uni-app中,利用微信小程序提供的API,例如通过`wx.request()`...

    baqianxin.github.io:见闻杂记

    用户可以在GitHub仓库中创建一个名为用户名.github.io的仓库,然后将HTML、CSS和JavaScript等文件上传,GitHub会自动将这个仓库的内容发布为一个网站。 【GitHub仓库】 "baqianxin.github.io-master" 这个文件名...

    yangbinfx的博客文章-ruby部分备份

    jQuery与Rails的集成允许开发者使用熟悉的链式方法和简化的API来编写JavaScript代码。 2. **Ruby代码小计**:这里可能涵盖了Ruby编程的基础和进阶技巧,如变量、数据类型、控制流、方法定义以及面向对象特性,如...

    miniprogramThreeDynamic.zip

    2. **three.js**: three.js是基于WebGL的3D库,它简化了WebGL编程,提供了丰富的3D对象、光照、材质、动画等功能。在这个项目中,three.js用于加载和显示3D模型,以及处理模型的平移、旋转等交互操作。 3. **Glb...

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

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

    Miscellanea:不同的东西

    2. JavaScript文件:可能包含使用three.js库的代码,用于处理和显示多维数据。 3. HTML文件:可能包含用于展示和交互的页面结构,与CSS和JavaScript协同工作。 4. 数据文件:可能是JSON或其他格式的文件,存储了多维...

Global site tag (gtag.js) - Google Analytics