首页 > 代码库 > Sizzle一步步实现所有功能(一)
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")
1 (function( window ){ 2 3 var arr = []; 4 var select ; 5 var push = arr.push; 6 // http://www.w3.org/TR/css3-selectors/#whitespace 7 // 各种空白待穿正则字符串 8 var whitespace = "[\\x20\\t\\r\\n\\f]"; 9 // 带空格选择器正则,记忆无空格选择器10 var rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" );11 // 快速选择器正则 ID 或者 TAG(包括*) 或者 CLASS 选择器12 var rquickExpr = /^(?:#([\w-]+)|(\w+|\*)|\.([\w-]+))$/;13 14 // 浏览器代码正则15 var rnative = /^[^{]+\{\s*\[native \w/;30 // 入口31 function Sizzle( selector ){32 // 清除空格33 selector = selector.replace( rtrim, "$1" )34 var results = [];35 var match;36 var matcher;37 var elem;38 var m;39 var context = document;40 41 // 是否为最简选择器42 if( match = rquickExpr.exec( selector )){43 // Sizzle(‘#ID)44 if ( (m = match[1]) ) {45 elem = context.getElementById( m );46 if( elem ){47 results.push( elem );48 }49 return results;50 51 // Sizzle("TAG")52 }else if( (m = match[2]) ){53 push.apply( results, context.getElementsByTagName( selector ) );54 return results;55 56 // Sizzle(".CLASS") 57 }else if( (m = match[3]) ){58 // 支持getElementsByClassName59 if( support.getElementsByClassName ){60 push.apply( results, context.getElementsByClassName( m ) );61 return results;62 63 // 不支持getElementsByClassName64 }else {65 // 获取遍历所有元素66 // 如果元素类名与我们选择器匹配的类名相同,则插入到结果数组中67 var elems = document.getElementsByTagName(‘*‘);68 var pattern = new RegExp(selector.slice(1));69 for(var i = 0; i<elems.length; i++) {70 if(pattern.test(elems[i].className)){71 results.push(elems[i])72 }73 }74 }75 }76 }77 return results;78 }79 // 版本支持变量的对外访问入口80 var support = Sizzle.support = {};81 82 // 判断是否支持getElementsByClassName83 // 支持: IE<984 support.getElementsByClassName = rnative.test( document.getElementsByClassName );85 86 // 对外入口87 window.MSizzle = Sizzle;88 89 })(window)90 console.log(MSizzle("#id"))91 console.log(MSizzle(".class"))92 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一步步实现所有功能(一)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。