• 从右到左选择:位置伪类


    位置伪类好像天生克从右到左的选择器,处理起来非常复杂,大抵有以下三种情况

    1、位置选择器出现群组的最后面。这种情况相对简单,我们先跳过它,取得节点后再进行过滤,如“"div span:eq(0)”

            for (var selector ; selector = selectors[i++];) {
            /**********略**********/
            /*遍历DOM树,收集符合条件的节点*/
            }
            /*如果选择器群组包含位置伪类,则进行筛选*/
            if(pos && obj.nodes.length ){
                obj.nodes = posFilter(obj.nodes,pos);
            }
    

    posFilter函数:

        var posFilter = function(nodes,pos){
            var match = pos.match(reg_pseudo), name = match[1],value = match[3],node,ri = 0,i = 0,result = [],
            filter = dom._filters[name]
            value = (value === ""|| value === void 0) ? nodes.length - 1 : ~~value;
            for (; node = nodes[i];){
                if(filter(i++, value) )
                    result[ri++] = node;
            }
            return result;
        }
    

    2、位置伪类位于并联选择器的两边,如“div:eq(0),#aa.class”

                if(selector === ","){
                    if(pos && obj.nodes.length ){//处理位置伪类
                        obj.nodes = posFilter(obj.nodes,pos)
                        pos = false;
                    }
                    result = result.concat(obj.nodes);
                    //处理逗号另一边的选择器群组
                    match  = getCandidates(selectors,context,i);
                    i      = match[1];
                    pos    = match[2];
                    if(!match[0].length){
                        i = indexOf(selectors,",",i);
                        if(i===-1){
                            break;
                        }
                    }
                    obj = {
                        set:{},
                        proxy:proxyViaSelf,
                        nodes:match[0]
                    }
                    flag_sort = true;
                }
    

    如果位置伪类出现在中间并且不靠近并联选择器,如“form span:eq(1) strong”。毫无疑问,我们只能用递归收拾它了。

    //比如form span:eq(1) strong
            ":":function(selector,obj,flag_xml,flag_not,doc,selectors,i){//★★★★(9)伪类
                var match = selector.match(reg_pseudo), name = match[1];
                if(one_position[name]){//位置伪类
                    var last = indexOf(selectors,",",i);
                    last = last === -1 ? selectors.length :last;
                    obj.args = [dom.query(selectors.slice(i-1,last),doc,flag_xml,flag_not)];//我们在这里筛选出匹配“form span:eq(1)”的节点
                    obj.filter = function(nodes){//过滤器,用于strong与eq(0)之间的后代选择器对应的代理器
                        return indexOf(nodes,this) > -1;
                    },
                    obj.i = last;
                }
            }
    

    2010.12.16日补充

    如果我们对原来的选择器群组做一些调整,或者能简化这逻辑,如div:eq(0)变成:eq(0)^div,那么从右到左选择时,自然成为div,:eq(0)的选择顺序。不用说,我们又需要一个强大的正则来处理它。

  • 相关阅读:
    如何在三维坐标中选择点
    java slider
    java combobox 多选框
    java BorderFrame.java
    java radioButton
    java checkbox
    java 文本窗口
    constexpr
    测试框架
    java 计算器
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/1905166.html
Copyright © 2020-2023  润新知