在递归中删除当前父节点

时间:2013-06-18 12:13:35

标签: javascript html

我创建了多个class="extra"的div。然后我为每个div添加删除按钮,以便分别删除每个div。所以我的代码是:

  var exr = document.getElementsByClassName("extra");           
    for(var i = 0 ;i<exr.length;i++){         
        var delbt = document.createElement("button");
        delbt.className="floatbutton_3 font_b"
        delbt.innerHTML="delete";
        exr[i].appendChild(delbt);
        delbt.onclick=  function(i){ return function(){ exr[i].parentNode.removeChild(exr[i]) } }(i);
   }

问题是,按钮无法移除应删除的按钮。似乎在最后一次删除后,索引被更改了。如何避免这种情况发生?

谢谢!

7 个答案:

答案 0 :(得分:0)

代码看起来像它应该工作,但只要你不添加或删除元素。这就是你在做什么。

有一个更简单,更可靠的解决方案:您可以在事件处理程序中使用this来引用当前元素。

delbt.onclick = function() {
    var div = this.parentNode; // you want to remove the div, not the button
    div.parentNode.removeChild(div);
};

我建议您阅读quirksmode.org上的the excellent articles about event handling,特别是关于traditional event handling(因为这就是您所使用的内容)。

答案 1 :(得分:0)

这样做......

var exr = document.getElementsByClassName("extra");           
for(var i = 0 ;i<inserter.length;i++){         
    var delbt = document.createElement("button");
    delbt.className="floatbutton_3 font_b"
    delbt.innerHTML="delete";
    exr[i].appendChild(delbt);
    delbt.index = i;
    delbt.onclick=  function(i){ var me = this; return function(){ exr[me.index].parentNode.removeChild(exr[i])    } }(i);
}

答案 2 :(得分:0)

使用this函数中的onclick来引用所点击的按钮 - 因此,将excr[i]替换为this.parentNode,您的代码应按预期执行。

答案 3 :(得分:0)

我将添加一个jQuery解决方案:

$('.extra').append(function() {
    return $('<button />', {'class':'floatbutton_3 font_b', html:'delete'});
});

$('.floatbutton_3').on('click', function() {
    $(this).closest('div').remove();
});

FIDDLE

答案 4 :(得分:0)

由于getElementsByClassName()会返回实时集,因此您可以先制作一份浅色副本:

var exr = [].slice.call(document.getElementsByClassName("extra"), 0);

答案 5 :(得分:0)

getElementsByClassName()返回HTMLCollection。这是一个实时列表,在底层结构发生变化时会发生变化。因此,即使您没有激活地从列表中删除元素,当您删除相应的HTML元素时,它们仍将自动从中删除。

通过将i传递给匿名函数,您可以修复索引。因此,每当您单击第三个删除按钮时,它将尝试删除列表中的第三个元素。但是如果你已经删除了第一个和第二个元素,那么列表也会被修改。因此,您的第三个按钮将由列表中的第一个项目表示,但它会尝试找到第三个按钮。

要避免此问题,您可以将完整元素传递给匿名函数,而不仅仅是索引:

for(var i = 0 ;i<exr.length;i++){         
    var delbt = document.createElement("button");
    delbt.className="floatbutton_3 font_b"
    delbt.innerHTML="delete";
    exr[i].appendChild(delbt);
    delbt.onclick = function(el){ return function(){ el.parentNode.removeChild(el) } }(exr[i]);
}

答案 6 :(得分:0)

您可以在点击事件中使用currentTarget。

这只会删除点击按钮的父div。

var exr = document.getElementsByClassName("extra");
for(var i = 0 ;i<exr.length;i++){
    var delbt = document.createElement("button");
    delbt.className="floatbutton_3 font_b"
    delbt.innerHTML="delete";
    exr[i].appendChild(delbt);
    delbt.onclick=  function( event ){
        event.currentTarget.parentElement.remove();
    }
}