把selector字符串,改装成function的字符串,然后new Function(s)出来。
去除伪类部分的代码,简化成如下:
<script> var Selector={ /* * CSS selector属性运算符 */ _operators:{ //以下表达式,aa表示attr值,vv表示比较的值 '': 'aa',//isTrue|hasValue '=': 'aa=="vv"',//equal '!=': 'aa!="vv"', //unequal '~=': 'aa&&(" "+aa+" ").indexOf(" vv ")>-1',//onePart '|=': 'aa&&(aa+"-").indexOf("vv-")==0', //firstPart '^=': 'aa&&aa.indexOf("vv")==0', // beginWith '$=': 'aa&&aa.lastIndexOf("vv")==aa.length-"vv".length', // endWith '*=': 'aa&&aa.indexOf(v)>-1' //contains }, /* * 常用的Element属性 */ _attrGetters:function(){ var o={'class': 'el.className', 'for': 'el.htmlFor', 'href':'el.getAttribute("href",2)'}; var attrs='name,id,className,value,selected,checked,disabled,type,tagName,readOnly'.split(','); for(var i=0,a;a=attrs[i];i++) o[a]="el."+a; return o; }(), /* * 把一个selector字符串转化成一个过滤函数. * @method selector2Filter * @param {string} sSelector: 过滤selector,这个selector里没有关系运算符(", >+~") * @returns {function} : 返回过滤函数。 * @example: var fun=selector2Filter("input.aaa");alert(fun); */ selector2Filter: function(sSelector) { var s=sSelector, reg=/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/g, //属性选择表达式解析,thanks JQuery sFun=[]; s=s.replace(/\:([\w\-]+)(\(([^)]+)\))?/g,function(a,b,c,d,e){pseudos.push([b,d]);return "";}) //伪类 .replace(/^\*/g,function(a){//任意tagName缩略写法 sFun.push('el.nodeType==1');return '' }) .replace(/^([\w\-]+)/g,function(a){//tagName缩略写法 sFun.push('el.tagName=="'+a.toUpperCase()+'"');return '' }) .replace(/([\[(].*)|#(\w+)|\.(\w+)/g, function (a, b, c, d) { //id缩略写法//className缩略写法 return b || c&&'[id="'+c+'"]' || d&&'[className~="'+d+'"]'; }) .replace(reg,function(a,b,c,d,e){//普通写法[foo][foo=""][foo~=""]等 var attrGetter=Selector._attrGetters[b] || 'el.getAttribute("'+b+'")'; sFun.push(Selector._operators[c||''].replace(/aa/g,attrGetter).replace(/vv/g,e||'')); return ''; }); if(s.length) {throw "Unsupported Selector:\n"+sSelector+"\n"+s;} if(sFun.length){ sFun='return ('+sFun.join(")&&(")+');'; alert(sFun); return new Function("el",sFun); } return function(el){return true;}; } }; Selector.selector2Filter('div.aaa.bbb[readOnly]'); </script>
这其实是一个很有用的功能。不明白sizzle为什么不顺便提供出来。