从右到左选择最大的好处有两个:1、如果不出现并联选择器的情况下了,经过一系列筛选后得到的结果就是自然按DOM树的顺序排列,2、之后的每次筛选的节点只会减少不会变多。
var reg_find =/(^[\w\u00a1-\uFFFF][\w\u00a1-\uFFFF-]*)|^(\*)|^#([\w\u00a1-\uFFFF-]+)|^\.([\w\u00a1-\uFFFF-]+)|^:(root)|^:(link)/ function getCandidates(selectors,context,s){ var match = selectors[s].match(reg_find), nodes,node; if(match){ if(match[1] || match[2] ){//标签或通配符选择器 nodes = dom.queryTag(match[1] || match[2],context); }else if(match[3] && context.getElementById){//ID选择器 node = context.getElementById(match[1]); nodes = node && [node] || [] }else if(match[4] && context.getElementsByClassName){//类选择器 nodes = dom.slice(context.getElementsByClassName(match[4])); }else if(match[5] && context.documentElement){//根伪类 nodes = [context.documentElement] }else if(match[6] && context.links){//链接伪类 nodes = dom.slice(context.links); } } if(nodes){ s++ }else{ nodes = dom.queryTag("*",context); } return [nodes,s]; }
//2011.1.3 var reg_find =/(^[\w\u00a1-\uFFFF][\w\u00a1-\uFFFF-]*)|^(\*)|^#([\w\u00a1-\uFFFF-]+)|^\.([\w\u00a1-\uFFFF-]+)|^:(root)|^:(link)/; var getCandidates = function(selectors,context,flag_xml,transport){ //种子选择器,用于选取候选集的选择器 //如果最后一个为通配符,那就取它,如果不存在关系选择器,那就取最后一个,否则取最后一个关系选择器紧挨着的右边那个选择器 var n = selectors.length, m = n - 1, index = 0, match, nodes,one = one_relation,reg = reg_find while(--n){ match = selectors[n]; if(one[match]){ index = n !== m ? n + 1 : m break; } } match = selectors[index].match(reg); if(match){ if(match[1]){//标签或通配符选择器 match = flag_xml ? match[1] : match[1].toUpperCase(); nodes = dom.queryTag(match,context); }else if(match[2]){ nodes = dom.queryTag("*",context); transport[3] = iterators.parents; }else if(match[3] && context.getElementById){//ID选择器 nodes = context.getElementById(match[3]); nodes = nodes && [nodes] || []; }else if(match[4] && context.getElementsByClassName){//类选择器 nodes = dom.slice(context.getElementsByClassName(match[4])); }else if(match[5] && context.documentElement){//根伪类 nodes = [context.documentElement]; }else if(match[6] && context.links){//链接伪类 nodes = dom.slice(context.links); } } if(nodes){ selectors.splice(index,1); }else{ nodes = dom.queryTag("*",context); } transport[0] = nodes; //结果集 transport[1] = nodes.concat(); //映射集 }
getCandidates : function(selectors,context,flag_xml){ //种子选择器,用于选取候选集的选择器 //如果最后一个为通配符,那就取它,如果不存在关系选择器,那就取最后一个,否则取最后一个关系选择器紧挨着的右边那个选择器 var nodes, reg = reg_find, last = selectors.length - 1, match = selectors[last].match(reg); if(match[1]){//标签 match = flag_xml ? match[1] : match[1].toUpperCase(); nodes = context.getElementsByTagName(match); }else if(match[2]){//ID选择器 if(context.getElementById){ match = context.getElementById(match[2]); nodes = match ? [match] : [] } }else if(match[3]){//类选择器 if(context.getElementsByClassName) nodes = context.getElementsByClassName(match[3]); }else if(match[4]){//name属性 if(context.getElementsByName) nodes = context.getElementsByName(match[4]); }else if(match[5] ){//链接伪类 if(context.links) nodes = context.links; }else if(match[6] ){//根伪类 if(context.documentElement) nodes = [context.documentElement]; } if(nodes){ selectors.length = last; }else{ nodes = context.getElementsByTagName("*"); } return nodes; }, var reg_find = /(^[\w\u00a1-\uFFFF\-\*]+)|^#([\w\u00a1-\uFFFF-]+)|^\.([\w\u00a1-\uFFFF-]+)|\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]|^:(link)|^:(root)|(\S+)/;