如何递归删除多个子节点而不会搞乱索引?

时间:2012-03-23 22:38:18

标签: javascript dom

JSFiddle网址:http://jsfiddle.net/sFe45/

代码:

<html>
    <head>
        <title>Foo</title>
        <script type="text/javascript">

var target;
var anchor;

function removeTags(node){
    for (var i = 0; i < node.childNodes.length; i++) {
        var childNode = node.childNodes[i];
        if (childNode.nodeType == 1) {
            node.removeChild(childNode);
            continue;
        } 
        removeTags(childNode);
    }
}

window.onload = function() {
    target = document.getElementById('target');
    anchor = document.getElementById('anchor');
    anchor.onclick = function() {
        removeTags(target);
    }
}

        </script>
    </head>
    <body>
        <div id="target">
            <p>
                <a href="#" id="anchor">Remove tags</a>
            </p>

            Text

            <p>Para 1</p>
            <p>Para 2</p>
            <p>Para 3</p>
            <p>Para 4</p>
            <p>Para 5</p>
            <p>Para 6</p>
            <p>Para 7</p>
            <p>Para 8</p>
            <p>Para 9</p>
            <p>Para 10</p>
            Text
        </div>
</html>

正如您将在JSFiddle URL中注意到的,当您单击“删除标记”链接时,removeTags()无法删除备用段落元素。原因是当removeTags从其父节点中删除子节点时,剩余的子节点在node.childNodes数组中向左移动一个位置。

如何以整洁的方式解决这个问题?

1 个答案:

答案 0 :(得分:3)

向后计数:

for (var i = node.childNodes.length - 1; i >= 0; i--) {

Updated fiddle

或者,您可以使用lastChildpreviousSibling

var prev;
for (var child = node.lastChild; child; child = prev) {
    prev = child.previousSibling;

    if (child.nodeType == 1) {
        node.removeChild(child);
        continue;
    } 

    removeTags(child);
}

Updated fiddle

单独:

  

...剩余的子节点在node.childNodes数组中向左移动一个位置......

NodeList数组。