如何迭代 children 的变化集

How to iterate over changing set of children

我正在使用 vanilla javascript 迭代元素的 children,基于 class 删除它们。但是,我对处理嵌套元素感到厌烦。

这里是代码的简化版本:

var replacements = [];
var children = el.getElementsByTagName('*');
for(var i = 0; i < children.length; i++) {
    var child = children[i];
    if(should_delete(child)) { /*just checking for the class "delete-me"*/
        replacements.push(child.outerHTML);
        var filler = document.createComment('deleted');
        child.parent.replaceChild(child);
    }
}

最后,我需要一个包含替换发生的注释的元素,以及与注释集一对一匹配的替换值数组。

但是,我遇到以下问题html

<div class="wrap">
    <div class="outer">
        <div class="delete-me">test</div>
        <div class="delete-me">
            <div class="delete-me">test2</div>
            <div class="delete-me">test3</div>
        </div>
        <div class="delete-me">test4</div>
    </div>
    <div class="delete-me">test5</div>
</div>

最终结果应该是:

与数组:

[
    '<div class="delete-me">test</div>',
    '<div class="delete-me"><div class="delete-me">test2</div><div class="delete-me">test3</div></div>',
    '<div class="delete-me">test4</div>',
    '<div class="delete-me">test5</div>'
]

但是,它似乎很早就失败了,因为 children pseudo-array 在我身上不断变化,以匹配 DOM.

的变化状态

如何让 children pseudo-array 随着 DOM 的变化而变化,同时仍然平滑地迭代它,而不存储已经被替换的元素的内容?

向后迭代。

for( i = children.length-1; i>=0; i--)

这将确保,即使您最终删除了元素,每个元素都会依次出现。您甚至可以添加元素并让它正常工作,只要这些添加的元素在添加它们的元素之后。

想通了...

我没有使用实时集合或静态数组,而是需要递归遍历 dom 树,边走边删除。

var replacements = [];
var processChildren = function(children) {
    var children_a = []; // this array exists so that children wont change as we delete elements
    for(var i = 0; i < children.length; i++) {
        children_a.push(children[i])
    }
    for(var i = 0; i < children_a.length; i++) {
        var child = children_a[i];
        if(should_delete(child)) { /*just checking for the class "delete-me"*/
            replacements.push(child.outerHTML);
            var filler = document.createComment('deleted');
            child.parent.replaceChild(filler, child);
        } else {
            processChildren(child.children);
        }
    }
}
processChildren(el.children);