Company logo
  • Empleos
  • Bootcamp
  • Acerca de nosotros
  • Para profesionales
    • Inicio
    • Empleos
    • Cursos y retos
    • Preguntas
    • Profesores
    • Bootcamp
  • Para empresas
    • Inicio
    • Nuestro proceso
    • Planes
    • Pruebas
    • Nómina
    • Blog
    • Comercial
    • Calculadora

0

130
Vistas
Remove multiple children from DOM (JS)

I am trying to remove certain children from DOM by iterating through them. I have a table, and I am looping through the children and removing some like this:

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

When this code is run, some of the children that meet the condition testRow.textContent === "false" are removed, but other rows that meet the condition are not removed.

Logging out t.children.lengh as the loop goes on reveals that the size is decreasing (due to the children being removed). My theory is that removing a child messes up the iterator. I tried rewriting this code as a for loop and got the same result: some children are "skipped over" and not removed.

Ideas on how to remove certain children of a DOM element (based on dynamically pulled data)?

7 months ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

This uses deleteRow taking the index of the row and using a traditional for loop iterating backwards from the end of the table rows to the beginning, it also utilizes the rows property of the table element:

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>

7 months ago · Juan Pablo Isaza Denunciar

0

table.children is an HTMLCollection; it gets updated as you change the document. You can convert it to a normal array so that changes to the DOM won't affect the contents that you're iterating through.

In the example below I've used the spread operator (...) to create the new array, but you could use Array.from instead e.g. 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>

Because [...tbody.children] is a normal array you can use functions like filter and forEach if you like, e.g.:

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>

7 months ago · Juan Pablo Isaza Denunciar

0

This solution I found works for all DOM types (vs just tables in Ryan Wilson's answer). Just decrement the index each time a DOM object is removed so that it will re-run the loop for the new ith element (because the previous will have been removed):

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--;
  }
}
7 months ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos