從右至左選擇最大的好處有兩個: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+)/;