自从jQuer1.4后,选择器就独立出来了,作为了一个开源的项目Sizzle,据说此选择器的性能远远超过其他框架的选择器。而Sizzle中两把利剑就是Sizzle.find和Sizzle.filter.今天先介绍第一把利剑Sizzle.find().
1: Sizzle.find = function(expr, context, isXML){ 2: //此时传递进来的选择都是独立的选择字符串,没有层级关系 如“+” “~” “ ”“>” 3: //set用来存储结果 match用来存储选择字符串分离的结果 4: var set, match; 5: //如果选择字符串为空则返回的结果集也为空 6: if ( !expr ) { 7: return []; 8: } 9: //order存储的是寻找匹配的顺序 order: [ "ID", "NAME", "TAG" ], 10: //按此顺寻匹配 11: for ( var i = 0, l = Expr.order.length; i < l; i++ ) { 12: //获取匹配类型 13: var type = Expr.order[i], match; 14: 15: if ( (match = Expr.leftMatch[ type ].exec( expr )) ) { 16: //leftMatch是存储各种匹配类型获取参数的正则表达式 17: //如leftMatch["ID"]为(^(?:.|\r|\n)*?)#((?:[\w\u00c0-\uFFFF-]|\\.)+)(?![^\[]*\])(?![^\(]*\)) 18: //由此正则表达式可见match是匹配参数的的前缀如tr#5,match[1]就是tr,match[2]为5 19: var left = match[1]; 20: match.splice(1,1); 21: //如果匹配类型字符串(# . TAG)前面没有注释字符‘\\’(说明此匹配类型字符串有效) 22: if ( left.substr( left.length - 1 ) !== "\\" ) { 23: //将用来参数中用来转义的双斜杠去掉 24: match[1] = (match[1] || "").replace(/\\/g, ""); 25: //Expr是一个对象,调用其find对象的相应匹配属性的寻找方法。那里会调用浏览器原生的获得元素的方法 26: //例如Expr.find["ID"]的函数为 27: //ID: function(match, context, isXML){ 28: //这里调用了浏览器原生的getElementById 29: // if ( typeof context.getElementById !== "undefined" && !isXML ) { 30: // var m = context.getElementById(match[1]); 31: // return m ? [m] : []; 32: // } 33: // } 34: set = Expr.find[ type ]( match, context, isXML ); 35: //如果返回的结果集不为空则将匹配的字符串删去,并跳出循环(选择字符串中的其他部分在另一把利器filter会被用作对此结果集进行过滤的过滤参数) 36: if ( set != null ) { 37: expr = expr.replace( Expr.match[ type ], "" ); 38: break; 39: } 40: } 41: } 42: }
其实Sizzle这把利器find还是比较简单的,filter则相对较难,但这里正则表达式的写法是很值得借鉴的