使用 divs.Only JS 动态删除列表

Delete dynamically a list with divs.Only JS

当我选中所有复选框并按下按钮时,始终存在最后一个节点。 我知道这是因为 parentNode 并且因为 DOM 树上的索引仍在内存中或类似的东西中。
某人可以帮助我了解该怎么做吗,我将不胜感激。

function deleteChecked() {
    var node_listFields = document.getElementsByClassName('fields');
    var checkboxes = document.getElementsByClassName("check");
    for (var i = 0; i < checkboxes.length; i++) {
        if (checkboxes[i].checked) {
            node_listFields[i].parentNode.removeChild(node_listFields[i]);
        }

    }
}
<input type="button" value="Delete" onclick="deleteChecked()" />
<div class="fields">
    <input type="checkbox" class="subCheck1 check" />Θέρμανση
    <input type="text" />

<br></br></div>
<div class="fields">
    <input type="checkbox" class="subCheck1 check" />Διάφορα
    <input type="text" />

<br></br></div>
<div class="fields">
    <input type="checkbox" class="subCheck1 check" />Διάφορα Yλικά
    <input type="text" />

<br></br></div>
<hr/>

?

那是因为 getElementsByClassName 返回的 HTMLCollection 对象是活动的,这意味着当您删除其中的一个节点时,它会自动更新(因此,您的 i 现在指向一个错误的项目),即在一次删除后导致错误,这就是为什么只有一个项目被删除的原因。

正确的方法是转换成数组(或使用 document.querySelectorAll(),returns 一个非活动列表)

function deleteChecked() {
  var node_listFields = document.getElementsByClassName('fields');
  // This converts to an array.
  var nodeArray = [].slice.call(node_listFields);

  var onlyCheckedArray = nodeArray.filter(function findIfCheckboxIsChecked(node) {
    // Returns if the checkbox inside this node is checked.
    return node.querySelector('.check').checked;
  })

  // Here onlyCheckedArray is an array with nodes with only checked checkboxes.
  // So let's remove them all!

  onlyCheckedArray.forEach(function removeNode(node) {
    node.parentNode.removeChild(node);
  });
}
<input type="button" onclick="deleteChecked()" />
<div class="fields">
  <input type="checkbox" class="subCheck1 check" />Θέρμανση
  <input type="text" />
</div>
<br></br>
<div class="fields">
  <input type="checkbox" class="subCheck1 check" />Διάφορα
  <input type="text" />
</div>
<br></br>
<div class="fields">
  <input type="checkbox" class="subCheck1 check" />Διάφορα Yλικά
  <input type="text" />
</div>
<br></br>
<hr/>

然后 jsFiddle

我遇到了同样的问题,并使用回归迭代解决了它。

据我了解,DOM 节点索引始终必须固定:0,1,2,3...:[=​​40=]


渐进迭代(i=0; i<3; i++){

  • i = 0 :
    • checkbox[0]已删除;
    • checkbox[1] 成为新的 checkbox[0] 因为 DOM 节点索引总是以 0;
  • i = 1 :
    • checkbox[1] 被删除,checkbox[0] 留在 DOM (跳过 1 个节点) ;
    • checkbox[2]变新checkbox[1];
  • i = 2 :
    • checkbox[2]被删除,checkbox[0] & [1] 停留在 DOM(跳过 2 个节点);
    • node[3]变新node[2];
  • 结束循环};

2 个跳过的复选框。需要重复循环直到剩下不到 2 个框,因为每次都会跳过其他框。

var inputElems = document.getElementsByTagName("input");
for(var i = 0; i<inputElems.length; i++){
    if(inputElems[i].type === "checkbox" && inputElems[i].checked === true) {
        inputElems[i].parentNode.remove();
    }
}

JSFiddle


回归迭代(i=2; i>=0; i--){

  • i = 2 :
    • checkbox[2] 已删除(索引中的最后一个复选框);
    • node[3](不是复选框)成为新的node[2];
  • i = 1 :
    • checkbox[1] 已删除,(更新索引中的最后一个复选框);
    • node[2](不是复选框)成为新的node[1];
  • i = 0 :
    • checkbox[0] 已删除,(更新索引中的最后一个复选框);
    • node[1](不是复选框)成为新的node[0](没有更多的复选框!);
  • 结束循环};

跳过的复选框:0。

var inputElems = document.getElementsByTagName("input");
for(var i = inputElems.length-1; i>= 0; i--){
    if(inputElems[i].type === "checkbox" && inputElems[i].checked === true) {
        inputElems[i].parentNode.remove();
    }
}

JSFiddle