从右到左选择:获取候选集

从右到左选择最大的好处有两个: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+)/;

原文地址:https://www.cnblogs.com/rubylouvre/p/1903839.html