簡體   English   中英

在后序遍歷中刪除元素節點

[英]Remove element nodes in post-order traversal

說我有以下HTML(濃縮):

<div><div><div><ul><li>Text</li></ul></div></div></div>
<div><div><div><ul><li>Text 2</li></ul></div></div></div>
<div><div><div><ul><li>Text 3</li></ul></div></div></div>

我想首先刪除最低的子元素,直到最終刪除父元素,然后轉到下一個父元素及其子元素。 這可以通過一個簡單的循環輕松完成,該循環遍歷每個子元素,刪除它,然后刪除下一個子元素(即前一個子元素的父元素):

var children = $("body").find("*");
var i = children.length;
function loop() {
    $(children[i]).remove();
    i--;
    if (i > -1) {
        setTimeout(loop, 20);
    }
}
loop();

但問題是,它首先從最低的父元素中刪除子元素。 如果您使用我的測試標記運行此代碼 ,您可以看到我的意思。

我想從最頂層的父節點中刪除子元素,然后向下工作,從而顛倒上述代碼的順序。 我能用以下代碼完成此操作

var parents = $("body").children(":not(:empty)");
var i = 0;
var speed = 1000;
function loop() {
    var children = $(parents[i]).find("*");
    var x = children.length;
    function inside() {
        $(children[x]).remove();
        x--;
        if (x > -1) {
            setTimeout(inside, speed);
        } else if (i < parents.length) {
            $(parents[i - 1]).remove();
            loop();
        } else if (i === parents.length) {
            $(parents[i - 1]).remove();
        }
    }
    inside();
    i++;
}
loop();

但是,此代碼的問題在於它只反轉了相對於父元素的刪除順序。 如果父項中有多個子元素,它仍將按默認升序(從下到上)刪除它們

因此,我的問題是,如何以更清晰的方式刪除所有元素,無論有多少子元素,都按降序刪除? 必須有比我嘗試的更好的方法。 jQuery也不是必需的。 setTimeout的原因是因為我需要在刪除元素之間有一個延遲。 像往常一樣,我可能忽略了一些相對簡單的事情,所以請耐心等待。

重申一下,如果HTML看起來像這樣:

<div>
    <div>Child 1</div>
    <div>Child 2</div>
    <div>
        <div>Child 3</div>
        <div>Child 4</div>
    </div>
</div>

我希望它按以下順序刪除:

  1. 孩子1
  2. 孩子2
  3. 孩子3
  4. 孩子4

偽代碼中的算法思想:

RemoveNode( node) { 
for(i=node.children.length-1;i>=0;i--){
    RemoveNode(node.children[i]);
}
remove(self);
return;
}

根據偽代碼添加了實際代碼:

function RemoveNode(node){
    for(var i = node.children.length - 1; i >= 0; i--){
        RemoveNode(node.children[i]);
    }
    $(node).remove();
}

帶有中斷的偽代碼,看看算法是如何工作的。 不知道為什么,但我不能讓它延遲工作。

function RemoveNode(node){
    for(var i = node.children.length - 1; i >= 0; i--){
      RemoveNode(node.children[i]);
        alert("hi");
    }
    $(node).remove();
}

RemoveNode($(".parent")[0]);

首先使用以下遞歸函數構建DOM樹的后序(aka child first)版本:

var nodes = [];

function generate()
{
    $(this).children().each(generate);
    nodes.push(this);
}

generate.call($('body'));

然后,按正常方式迭代:

var i = 0;

function loop() 
{
    $(nodes[i]).remove();
    if (++i < nodes.length) {
        setTimeout(loop, 1000);
    }
}

loop();

演示

我認為這樣做你想要的:

removeLast();

function removeLast(){
    var o = document.getElementById("root"), p = o;
    while (p.lastChild) p = p.lastChild;
    p.parentNode.removeChild(p);
    if(o != p) setTimeout(removeLast,20);
}

小提琴

我不確定我完全理解這個問題,但也許這就是你要找的東西?

演示: http//jsfiddle.net/xT3Au/1/

var $parents = $('.parent');

$parents.each(function(i) {
    var $tree = $(this).find('*').addBack();
    $tree.sort(function(a, b) {
        return $(a).find('*').length - $(b).find('*').length;
    }).each(function(j, el) {
        var speed = 1000 * (j + 1 + i * $tree.length);
        setTimeout(function(){ $(el).remove() }, speed);
    });
});

我認為使用類來了解哪些父母應該遵循哪種順序會更容易。 否則很難弄清楚訂單。 如果我弄錯了,請嘗試使用排序功能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM