从 DOM 中删除多个 children (JS)

Remove multiple children from DOM (JS)

我正在尝试通过迭代从 DOM 中删除某些 children。我有一个 table,我正在遍历 children 并删除一些这样的内容:

for (const row of table.children) {
  const testRow = row.children[2];
  if (testRow.textContent === "false") {
    table.removeChild(row);
  }
}

当此代码为运行时,部分children符合条件testRow.textContent === "false"被去除,但其他符合条件的行不去除移除.

随着循环的进行注销 t.children.lengh 显示大小正在减小(由于 children 被删除)。我的理论是删除 child 会弄乱迭代器。我尝试将此代码重写为 for 循环并得到相同的结果:一些 children 被“跳过”并且没有被删除。

关于如何删除 DOM 元素的某些 children 的想法(基于动态拉取的数据)?

这使用 deleteRow 获取行的索引并使用传统的 for 循环从 table 行的末尾向后迭代到开头,它还利用 rows 属性 table 元素:

window.addEventListener('DOMContentLoaded', function(){
   const tbl = document.querySelector('table');
   for(let a = tbl.rows.length - 1; a >= 0; a--){
      //you can modify this next condition to match what you want
      if(tbl.rows[a].cells[0].textContent === "Even"){
         tbl.deleteRow(a);
      }
   }
});
<table>
<tr><td>Even</td></tr>
<tr><td>Odd</td></tr>
<tr><td>Even</td></tr>
<tr><td>Odd</td></tr>
<tr><td>Even</td></tr>
<tr><td>Odd</td></tr>
<tr><td>Even</td></tr>
<tr><td>Odd</td></tr>
<tr><td>Even</td></tr>
<tr><td>Odd</td></tr>
<tr><td>Even</td></tr>
<tr><td>Odd</td></tr>
<tr><td>Even</td></tr>
<tr><td>Odd</td></tr>
<tr><td>Even</td></tr>
<tr><td>Odd</td></tr>
<tr><td>Even</td></tr>
<tr><td>Odd</td></tr>
<tr><td>Even</td></tr>
<tr><td>Odd</td></tr>
</table>

我发现这个解决方案适用于所有 DOM 类型(相对于 中的表)。每次删除 DOM 对象时只需递减索引,这样它将 re-run 新的 i 元素的循环(因为前一个将被删除):

for (let i = 0; i < t.children.length; i++) {
  const row = table.children[i];
  const testRow = row.children[2];
  if (testRow.textContent === "false") {
    table.removeChild(row);
    i--;
  }
}

如果元素为空,您可以使用 css :empty 选择器:

setTimeout(()=>{
    for (let el of document.querySelectorAll('tr td:empty')){
        el.remove()
    }
},2000)
td {border: 1px solid black;height:30px;}
<table>
<tr><td>text</td></tr>
<tr><td></td></tr>
<tr><td>text</td></tr>
<tr><td></td></tr>

</table>

table.children 是一个 HTMLCollection;它会在您更改文档时更新。您可以将其转换为普通数组,以便对 DOM 的更改不会影响您正在迭代的内容。

在下面的示例中,我使用了扩展运算符 (...) 来创建新数组,但您可以使用 Array.from 代替,例如Array.from(tbody.children).

const tbody = document.querySelector('table tbody');

console.log(tbody.children.constructor.name);

for (const row of [...tbody.children]) {
  const testRow = row.children[1];
  if (testRow.textContent === "false") {
    tbody.removeChild(row);
  }
}
<table>
  <tbody>
    <tr><td>A</td><td>true</td></tr>
    <tr><td>B</td><td>false</td></tr>
    <tr><td>C</td><td>false</td></tr>
    <tr><td>D</td><td>true</td></tr>
    <tr><td>E</td><td>false</td></tr>
    <tr><td>F</td><td>true</td></tr>
  </tbody>
</table>

因为 [...tbody.children] 是一个普通数组,如果你愿意,你可以使用像 filter 和 forEach 这样的函数,例如:

const tbody = document.querySelector('table tbody');

[...tbody.children]
  .filter((row) => row.cells[1].textContent === "false")
  .forEach((row) => { tbody.removeChild(row); });
<table>
  <tbody>
    <tr><td>A</td><td>true</td></tr>
    <tr><td>B</td><td>false</td></tr>
    <tr><td>C</td><td>false</td></tr>
    <tr><td>D</td><td>true</td></tr>
    <tr><td>E</td><td>false</td></tr>
    <tr><td>F</td><td>true</td></tr>
  </tbody>
</table>