Sizzle一步步实现所有功能(一)
前提:
1.HTML5自带querySelectAll可以完全替代Sizlle,所以我们下面写的Sizzle,是不考虑QSA的。
2.作者考虑了大量兼容情况,比如黑莓4.6系统这样几乎接触不到的bug。这样学习价值不高却很费时间问题我不去考虑。主要考虑IE8,这也是Sizzle没被淘汰的最主要原因。
3.我喜欢采用var 声明每个变量,而不是一个var 声明好多变量。原因是我在一步步完善模仿的Sizzle,会有大量的修改。
4.Sizzle的原理实际很简单,真的就可以这样一句话遍历页面所有元素,对每个元素进行排除,符合的则插入到结果数组。但功能繁多,层级繁杂,难点是架构。
5.这是一篇超长的文章。
第一步:实现Sizzle('#ID),Sizzle("TAG"),Sizzle(".CLASS")
(function( window ){ var arr = [];
var select ;
var push = arr.push;
// http://www.w3.org/TR/css3-selectors/#whitespace
// 各种空白待穿正则字符串
var whitespace = "[\\x20\\t\\r\\n\\f]";
// 带空格选择器正则,记忆无空格选择器
var rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" );
// 快速选择器正则 ID 或者 TAG(包括*) 或者 CLASS 选择器
var rquickExpr = /^(?:#([\w-]+)|(\w+|\*)|\.([\w-]+))$/; // 浏览器代码正则
var rnative = /^[^{]+\{\s*\[native \w/; // 入口
function Sizzle( selector ){
// 清除空格
selector = selector.replace( rtrim, "$1" )
var results = [];
var match;
var matcher;
var elem;
var m;
var context = document; // 是否为最简选择器
if( match = rquickExpr.exec( selector )){
// Sizzle('#ID)
if ( (m = match[1]) ) {
elem = context.getElementById( m );
if( elem ){
results.push( elem );
}
return results; // Sizzle("TAG")
}else if( (m = match[2]) ){
push.apply( results, context.getElementsByTagName( selector ) );
return results; // Sizzle(".CLASS")
}else if( (m = match[3]) ){
// 支持getElementsByClassName
if( support.getElementsByClassName ){
push.apply( results, context.getElementsByClassName( m ) );
return results; // 不支持getElementsByClassName
}else {
// 获取遍历所有元素
// 如果元素类名与我们选择器匹配的类名相同,则插入到结果数组中
var elems = document.getElementsByTagName('*');
var pattern = new RegExp(selector.slice(1));
for(var i = 0; i<elems.length; i++) {
if(pattern.test(elems[i].className)){
results.push(elems[i])
}
}
}
}
}
return results;
}
// 版本支持变量的对外访问入口
var support = Sizzle.support = {}; // 判断是否支持getElementsByClassName
// 支持: IE<9
support.getElementsByClassName = rnative.test( document.getElementsByClassName ); // 对外入口
window.MSizzle = Sizzle; })(window)
console.log(MSizzle("#id"))
console.log(MSizzle(".class"))
console.log(MSizzle("div"))
1.rquickExpr.exec( selector )返回一个数组,exec方法返回一个数组,第0项是匹配的内容,第1项是第一个括号中记忆的内容,第2项是第一个括号中记忆的内容,依次类推。
console.log(/(1)|(2)|(3)/.exec('1')); //[ "1", "1", undefined, undefined ]
console.log(/(1)|(2)|(3)/.exec('2')); //[ "2", undefined, "2", undefined ]
console.log(/(1)|(2)|(3)/.exec('3')); //[ "3", undefined, undefined, "3" ]
2.判断浏览器是否支持某段代码的正则rnative = /^[^{]+\{\s*\[native \w/
Sizzle一步步实现所有功能(一)的更多相关文章
- Sizzle一步步实现所有功能(基本筛选)
第二步:实现:first,:last,:eq(),even,odd,:gt(),:lt(); :header,:root,:taget; :not(). ;(function( window ){ v ...
- Sizzle一步步实现所有功能(层级选择)
第二步:实现Sizzle("el,el,el..."),Sizzle("el > el"),Sizzle("el el"),Sizzl ...
- 基于.NetCore开发博客项目 StarBlog - (13) 加入友情链接功能
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
- 窥探Swift之数组安全索引与数组切片
今天是元宵节,祝大家元宵节快乐!在Swift中的数组和字典中下标是非常常见的,数组可以通过索引下标进行元素的查询,字典可以通过键下标来获取相应的值.在使用数组时,一个常见的致命错误就是数组越界.如果在 ...
- 2014年4月份第1周51Aspx源码发布详情
基于Extjs4+MVC4权限管理源码 2014-3-31 [VS2012]源码描述: 20140331更新:修改部门管理中bug 20140303更新:增加部门管理模块,主要包含部门添加,编辑,删 ...
- Socket网络编程(2)--服务端实现
中秋了,首先祝大家中秋快乐,闲着无事在家整一个socket的聊天程序,有点仿QQ界面,就是瞎折腾,不知道最后是不是能将所有功能实现. 如果你对socket不了解,请看这篇文章:http://www.c ...
- BOOST 线程完全攻略 - 扩展 - 可被关闭的线程类
本文假设读者已经基本了解boost线程库的使用方法. boost是个开源工程,线程这一块也在不断完善之中,到现在这个阶段,boost::thread仅仅实现了一个完美的技术框架,但是读者在实际使用中会 ...
- 【重新发布,代码开源】FPGA设计千兆以太网MAC(1)——通过MDIO接口配置与检测PHY芯片
原创博客,转载请注明出处:[重新发布,代码开源]FPGA设计千兆以太网MAC(1)——通过MDIO接口配置与检测PHY芯片 - 没落骑士 - 博客园 https://www.cnblogs.com/m ...
- 6个项目带你全面掌握Laravel框架
Laravel框架简介: Laravel是一套简洁.优雅的PHP Web开发框架(PHP Web Framework).它可以让你从面条一样杂乱的代码中解脱出来,帮你构建一个完美的网络APP,而且每行 ...
随机推荐
- raft 一致性算法
介绍: 过去, Paxos一直是分布式协议的标准,但是Paxos难于理解,更难以实现,Google的分布式锁系统Chubby作为Paxos实现曾经遭遇到很多坑. 来自Stanford的新的分布式协议研 ...
- ubuntu登陆后一闪回到登陆界面
ubuntu登陆后一闪回到登陆界面 最后发现居然是我的环境变量配置问题........ 解决方法: 先CTRL+ALT+F1 root进去, 查看nickleo用户为什么登录失败 ca ...
- python list求交集
方法一: a=[1,2,3] b=[1,3,4] c=list(set(a).intersection(set(b))) print c #[1,3] 这种方法是先把list转换为set,再用set求 ...
- Minimum Sum(思维)
Problem 1603 - Minimum Sum Time Limit: 2000MS Memory Limit: 65536KB Total Submit: 563 Accepted ...
- SQL Server中的临时表和表变量
SQL Server中的临时表和表变量 作者:DrillChina出处:blog2008-07-08 10:05 在SQL Server的性能调优中,有一个不可比拟的问题:那就是如何在一段需要长时间的 ...
- sublime常用快捷键整理(未完待续)
sublime常用快捷键整理: 基本操作 cmd+o 打开文件 cmd+w 关闭当前tab cmd+n 打开新页 cmd+shift+n 打开刚刚关闭的页签 一.选择命令 1.多个单词选择 cmd+d ...
- js判断手机的类型
var ua = navigator.userAgent;if(ua.match(/iPhone|iPod/i) != null){console.log("iphone代码"); ...
- 关于ASP.NET中的负载均衡
ASP.NET站点中做负载均衡: 基于HTTP协议我们可能发现我们要解决两点问题: 第一做到负载均衡,我们需要一个负载均衡器. 可以通过DNS轮询来做,在DNS服务器上配置为每次对我们做负载均衡的同一 ...
- (六)Android中Service通信
一.启动Service并传递参数 传递参数时只需在startService启动的Intent中传入数据便可,接收参数时可在onStartCommand函数中通过读取第一个参数Intent的内容来实现 ...
- L12 samba服务器搭建
在/data/share目录下建立三个子目录public.training.devel用途如下public目录用于存放公共数据,如公司的规章制度training目录用于存放公司的技术培训资料devel ...