zoukankan      html  css  js  c++  java
  • 从右到左选择:五大迭代器

    如果是从左到右,我们想过滤一些节点,就用现在手头上的节点就行了,但从右到左,我们就需要根据这些节点的父亲、孩子、兄弟进行过滤,而且过滤后,这些用作比较的节点不能丢弃掉,它们可以还要用于下一次的过滤。这样就存在一个代理关系,我们需要一些代理器来干这事情。当然像div.aaa是不需要代理器,但div div.aaa就需要了。在从左到右的情况下,我们所有说的关系选择器,主要有亲子兄长与相邻三种,遇到后代选择器,我们可以转化为通配符选择器与标签选择器。而在从右到左,关系选择器就包括后代通配符亲子兄长相邻五种,通配符实质是一种带层次关系的后代选择器。

        //取得候选集的共同父节点的合集
        var getParent = function(testee,result,yess,pid){
            while((testee = testee.parentNode)){
                pid = testee.uniqueID || (testee.uniqueID = dom.UID++);
                if(yess[pid]){
                    result = testee
                }
            }
            return result;
        }
         var iterators = {
            current:function(nextset){
                var set = this, nodes = this.nodes,tagName = this.tagName, filter = this.filter,args = this.args,
                result = [], testee, uid;
                for(var i = 0,ri = 0, node;node = nodes[i++];){
                    uid = node.uniqueID || (node.uniqueID = dom.UID++);
                    testee = set[uid] || node;
                    if((!tagName || tagName === testee.nodeName) && (!filter || filter.apply(testee,args))){
                        result[ri++] = node;
                        nextset[uid] = testee;
                    }
                }
                nextset.nodes = result;
            },
            parent:function(nextset){
                var set = this, nodes = this.nodes,tagName = this.tagName, filter = this.filter,args = this.args,
                result = [], yess = {}, testee, uid, pid;
                for(var i = 0,ri = 0, node; node = nodes[i++];){
                    uid =  node.uniqueID || (node.uniqueID = dom.UID++);
                    testee = set[uid] || node;
                    while((testee = testee.parentNode)  && testee.nodeType === 1 ){
                        pid = testee.uniqueID || (testee.uniqueID = dom.UID++);
                        if(yess[pid]){
                            result[ri++] = node;
                            nextset[uid] = testee;
                            break;
                        }
                        if((!tagName || tagName === testee.nodeName) && (!filter || filter.apply(testee,args))){
                            yess[pid] = result[ri++] = node;
                            nextset[uid] = testee;
                        }
                        break;
                    }
                }
                nextset.nodes = result;
            },
        iterators.parents = function (nextset) {
            var set = this, nodes = this.nodes, tagName = this.tagName, filter = this.filter, args = this.args, level = this.level, _level, result = [], testee, uid, pid, yess = {};
            for (var i = 0, ri = 0, node; node = nodes[i++];) {
                uid = node.uniqueID || (node.uniqueID = dom.UID++);
                testee = set[uid] || node;
                while ((testee = testee.parentNode)) {
                    if (testee.nodeType === 1) {
                        if (level) {
                            _level = level;
                            while (_level-- && (testee = testee.parentNode)) {
                            }
                            if (!testee) {
                                break;
                            }
                        }
                        pid = testee.uniqueID || (testee.uniqueID = dom.UID++);
                        if (yess[pid]) {
                            result[ri++] = node;
                            nextset[uid] =  nextset[yess[pid].uniqueID];
                            break;
                        }
                        if ((!tagName || tagName === testee.nodeName) &&
                            (!filter || filter.apply(testee, args))) {
                            yess[pid] = result[ri++] = node;
                            nextset[uid] = getParent(testee, result, yess, pid);
                            break;
                        }
                    }
                }
            }
            nextset.nodes = result;
        }
            border:function(nextset){
                var set = this, nodes = this.nodes,tagName = this.tagName, filter = this.filter,args = this.args,
                result = [], testee, uid;
                for(var i = 0,ri = 0, node;node = nodes[i++];){
                    uid = node.uniqueID || (node.uniqueID = dom.UID++);
                    testee = set[uid] || node;
                    while((testee = testee.previousSibling) && testee.nodeType === 1){
                        if((!tagName || tagName === testee.nodeName) && (!filter || filter.apply(testee,args))){
                            result[ri++] = node;
                            nextset[uid] =  testee;
                        }
                        break;
                    }
                }
                nextset.nodes = result;
            },
            borders:function(nextset){
                var set = this, nodes = this.nodes,tagName = this.tagName, filter = this.filter,args = this.args,
                result = [], yess = {}, testee, uid, pid;
                for(var i = 0,ri = 0, node;node = nodes[i++];){
                    uid = node.uniqueID || (node.uniqueID = dom.UID++);
                    testee = set[uid] || node;
                    while((testee = testee.previousSibling) && testee.nodeType === 1){
                        pid = testee.uniqueID || (testee.uniqueID = dom.UID++);
                        if(yess[pid]){
                            result[ri++] = node;
                            nextset[uid] = testee
                            break;
                        }
                        if((!tagName || tagName === testee.nodeName) && (!filter || filter.apply(testee,args))){
                            yess[pid] = result[ri++] = node;
                            nextset[uid] = testee;
                            break;
                        }
                    }
                }
                nextset.nodes = result;
            }
        }
    
    

    它们几个好相似,正在考虑是否动态生成它们……

    用时间截代替UID的筛选功能

    选择div div div

        
    3
    3

    后代

    var fathers = function () {
        var querytime = dom.querytime //new Date - 0
        var nodes = this[0],set = this[1],args = this[4], filter = this[5],_set = [], _nodes = [], i = 0, ri = 0,node, testee;
        while ((testee = set[i])) {
            node = testee; //node至始自终从候选集中甄选,testee则从set的元素的长辈里甄选
            while ((testee = testee.parentNode)) {
                if (testee.querytime === querytime) {
                    _set[ri] = testee;
                    _nodes[ri++] = nodes[i];
                    break;
                }
                if (testee.nodeName === "DIV") {
                    testee.querytime = querytime
                    _set[ri] = testee;
                    _nodes[ri++] = nodes[i];
                    break;
                }
            }
            i++;
        }
        this[0] = _nodes;
        this[1] = _set;
        this.length = 3;
    }
    

    亲子

    var father = function () {
        var querytime = dom.querytime;
        var nodes = this[0], set = this[1], args = this[4], filter = this[5], _set = [], _nodes = [], i = 0, ri = 0, node, testee;
        while ((testee = set[i])) {
            node = testee;
            while ((testee = testee.parentNode)) {
                if (testee.querytime === querytime) {
                    _set[ri] = testee;
                    _nodes[ri++] = node;
                    break;
                }
                if (testee.nodeName === "DIV") {
                    testee.querytime = querytime
                    _set[ri] = testee;
                    _nodes[ri++] = node;
                }
                break;
            }
            i++;
        }
        this[0] = _nodes;
        this[1] = _set;
        this.length = 3;
    }
    

    2011.1.26

    var border = function (expr, set, flag_xml) {
        var selector, filter = Rage.filter;
        expr = expr.replace(reg_tag, function ($) {
            selector = $ === '*' ? true : flag_xm ? $ : $.toUpperCase();
            return '';
        });
        for (var i = 0, n = set.length; i < n; i++) {
            if (testee = set[i]) {
                while ((testee = testee.previousSibling) && testee.nodeType !== 1) {};
                testee = testee && testee.nodeName === selector && testee || false;
            }
        }
        expr && filter.call(null, expr, set, true);
    }
    
    var parent = function (expr, set, flag_xml) {
        var selector, filter = Rage.filter;
        expr = expr.replace(reg_tag, function ($) {
            selector = $ === '*' ? true : flag_xm ? $ : $.toUpperCase();
            return '';
        });
        for (var i = 0, n = set.length; i < n; i++) {
            if (testee = set[i]) {
                testee = testee.parentNode;
                testee = testee && testee.nodeName === selector && testee || false;
            }
        }
        expr && filter.call(null, expr, set, true);
    }
    
    var borders = function (expr, set, flag_xml) {
        var selector, filter = Rage.filter,_filter = Rage._filter,flag_fn = false,old = expr,prop = 'previousSibling';
        expr = expr.replace(reg_first, function ($) {
            if (reg_tag.test($)) {
                selector = $ === '*' ? true : flag_xm ? $ : $.toUpperCase();
            } else {
                selector = $;
                flag_fn = true;
            }
            return '';
        });
        if (expr === old) {
            throw old + '存在语法错误';
        }
        _filter.call(null, selector, set, prop, flag_fn);
        expr && filter.call(null, expr, set, true);
    }
    
    var parents = function (expr, set, flag_xml) {
        var selector, filter = Rage.filter,_filter = Rage._filter, flag_fn = false,old = expr, prop = 'parentNode';
        expr = expr.replace(reg_first, function ($) {
            if (reg_tag.test($)) {
                selector = $ === '*' ? true : flag_xm ? $ : $.toUpperCase();
            } else {
                selector = $;
                flag_fn = true;
            }
            return '';
        });
        if (expr === old) {
            throw old + '存在语法错误';
        }
        _filter.call(null, selector, set, prop, flag_fn);
        expr && filter.call(null, expr, set, true);
    }
    
  • 相关阅读:
    数据库主从配置
    数据库导出导入
    MySQL命令行导出数据库
    [待完善]mycat使用(一)
    行转列group_concat()函数妙用
    sas和ssd盘写入数据效率对比
    MySQL库中表名忽略大小写设置的影响
    create table b1 as select * from b建表锁表测试
    SQL优化实战之加索引
    分区表主键不包含分区键报错ERROR 1105 (HY000)
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/1902938.html
Copyright © 2011-2022 走看看