Ruby's Louvre

每天学习一点点算法

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

从右到左选择:五大迭代器

如果是从左到右,我们想过滤一些节点,就用现在手头上的节点就行了,但从右到左,我们就需要根据这些节点的父亲、孩子、兄弟进行过滤,而且过滤后,这些用作比较的节点不能丢弃掉,它们可以还要用于下一次的过滤。这样就存在一个代理关系,我们需要一些代理器来干这事情。当然像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

<div class="bbb">3
  <div class="1">
    <div class="11">
    </div>
  </div>
  <div class="2">
  </div>
  <div class="3">
  </div>
</div>
<div class="aaa">3
  <div class="4">
  </div>
  <div class="5">
  </div>
  <div class="6">
  </div>
</div>

后代

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);
}

如果您觉得此文有帮助,可以打赏点钱给我支付宝1669866773@qq.com ,或扫描二维码

posted on   司徒正美  阅读(1206)  评论(0编辑  收藏  举报

编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
点击右上角即可分享
微信分享提示