前提:

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一步步实现所有功能(一)的更多相关文章

  1. Sizzle一步步实现所有功能(基本筛选)

    第二步:实现:first,:last,:eq(),even,odd,:gt(),:lt(); :header,:root,:taget; :not(). ;(function( window ){ v ...

  2. Sizzle一步步实现所有功能(层级选择)

    第二步:实现Sizzle("el,el,el..."),Sizzle("el > el"),Sizzle("el el"),Sizzl ...

  3. 基于.NetCore开发博客项目 StarBlog - (13) 加入友情链接功能

    系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...

  4. 窥探Swift之数组安全索引与数组切片

    今天是元宵节,祝大家元宵节快乐!在Swift中的数组和字典中下标是非常常见的,数组可以通过索引下标进行元素的查询,字典可以通过键下标来获取相应的值.在使用数组时,一个常见的致命错误就是数组越界.如果在 ...

  5. 2014年4月份第1周51Aspx源码发布详情

    基于Extjs4+MVC4权限管理源码  2014-3-31 [VS2012]源码描述: 20140331更新:修改部门管理中bug 20140303更新:增加部门管理模块,主要包含部门添加,编辑,删 ...

  6. Socket网络编程(2)--服务端实现

    中秋了,首先祝大家中秋快乐,闲着无事在家整一个socket的聊天程序,有点仿QQ界面,就是瞎折腾,不知道最后是不是能将所有功能实现. 如果你对socket不了解,请看这篇文章:http://www.c ...

  7. BOOST 线程完全攻略 - 扩展 - 可被关闭的线程类

    本文假设读者已经基本了解boost线程库的使用方法. boost是个开源工程,线程这一块也在不断完善之中,到现在这个阶段,boost::thread仅仅实现了一个完美的技术框架,但是读者在实际使用中会 ...

  8. 【重新发布,代码开源】FPGA设计千兆以太网MAC(1)——通过MDIO接口配置与检测PHY芯片

    原创博客,转载请注明出处:[重新发布,代码开源]FPGA设计千兆以太网MAC(1)——通过MDIO接口配置与检测PHY芯片 - 没落骑士 - 博客园 https://www.cnblogs.com/m ...

  9. 6个项目带你全面掌握Laravel框架

    Laravel框架简介: Laravel是一套简洁.优雅的PHP Web开发框架(PHP Web Framework).它可以让你从面条一样杂乱的代码中解脱出来,帮你构建一个完美的网络APP,而且每行 ...

随机推荐

  1. web api 文档声明

    namespaceHelloWebAPI.Controllers{     usingHelloWebAPI.Models;     usingSystem;     usingSystem.Coll ...

  2. 《面试题精选》15.O(logn)求Fibonacci数列

    题目:定义Fibonacci数列例如以下: /    0                      n=0 f(n)=      1                      n=1          ...

  3. JeeSite 企业信息化快速开发平台

    平台简介 JeeSite是基于多个优秀的开源项目,高度整合封装而成的高效,高性能,强安全性的开源Java EE快速开发平台. JeeSite本身是以Spring Framework为核心容器,Spri ...

  4. SecureCRT 绝佳配色方案

    终端有一个好的配色,不仅能保护自己的眼睛,也能给人一个好心情,本配色方案适合任意一种SSH客户端软件. 设置背景颜色 Options => Sessions options => Term ...

  5. RadioButtonList选择事件onclick

    <asp:RadioButtonList ID="rbtnFInvoiceType" runat="server" onclick="check ...

  6. UVA 1603 Square Destroyer

    题意: 给定一个火柴棒拼成的方格阵,然后去掉一些火柴棒,问至少再去掉几根火柴棒能够让图中一个正方形都没有. 思路: 1. 由于题目中给定了 n 的范围,2 * n * (n + 1) <= 60 ...

  7. 修改MyEclipse8.6的Servlet模板

    D:\Genuitec\Common\plugins\com.genuitec.eclipse.wizards_****.jar 解压jar包, 进入templates文件夹,修改生成Servlet模 ...

  8. QT5中的pro文件中为何要加入"QT += widgets"

    在pro文件里写"QT+=widgets"表示引入QtWidget这个module,qmake在生成makefile的时候,会设置好include path 和 lib path, ...

  9. C++中内存分配详解

    转载自51CTO.com           http://developer.51cto.com/art/201107/276154.htm 我们都知道,内存基本上分为静态存储区.堆区和栈区三大部分 ...

  10. Activity 切换 动画

    overridePendingTransition的简介   1 Activity的切换动画指的是从一个activity跳转到另外一个activity时的动画. 它包括两个部分:一部分是第一个acti ...