forEach 不访问 NodeList 中的所有元素
forEach does not access all elements in NodeList
因为现在可以在 NodeList
上调用 forEach
数组方法。我想知道为什么如果您在使用 forEach
循环时更改 childNodes
NodeList 的内容,forEach
不会检测到更改。
grid.childNodes.forEach(function(tableRow, index, nodeList) {
tableRow.remove();
});
在这里,我试图遍历我的 table(grid) 子元素并从 table 中删除每个子元素 (tableRow
)。但是,forEach
永远不会完全遍历每个元素,总是遗漏最后一个 tableRow
是 remove
d.I 认为它与 childNodes NodeList 正在运行有关,并且forEach 无法正确地遵循它或其他东西。
这是因为,在较低的级别上,.forEach()
仍在保持计数并使用元素的索引。当您删除一些时,您是从 array/node 列表的开头删除它们,然后索引器变得不准确,因为所有元素索引都必须向下移动一个。例如,曾经位于索引位置 5 的元素现在位于索引位置 4。
对于这样的事情,最好使用计数循环并从最后一个索引开始并向后工作删除元素。这将在循环期间保持适当的计数,因为不会修改元素到索引的映射。
这是一个例子:
let grid = document.getElementById("myTable");
document.querySelector("input").addEventListener("click", function(){
for(i = grid.childNodes.length-1; i > -1; i--) {
grid.removeChild(grid.childNodes[i]);
}
});
<table id="myTable">
<tr>
<td>Row 1</td>
</tr>
<tr>
<td>Row 2</td>
</tr>
<tr>
<td>Row 3</td>
</tr>
<tr>
<td>Row 4</td>
</tr>
<tr>
<td>Row 5</td>
</tr>
</table>
<input type="button" value="Delete Rows">
现在,如果您要使用 DOM Table API and .deleteRow()
,您还可以使这更简单一些
let grid = document.getElementById("myTable");
document.querySelector("input").addEventListener("click", function(){
for(i = grid.rows.length-1; i > -1; i--) {
grid.deleteRow(i);
}
});
<table id="myTable">
<tr>
<td>Row 1</td>
</tr>
<tr>
<td>Row 2</td>
</tr>
<tr>
<td>Row 3</td>
</tr>
<tr>
<td>Row 4</td>
</tr>
<tr>
<td>Row 5</td>
</tr>
</table>
<input type="button" value="Delete Rows">
当然,您可以通过清除 .innerHTML
.
来清除 table 中的所有内容
let grid = document.getElementById("myTable");
document.querySelector("input").addEventListener("click", function(){
grid.innerHTML = "";
});
<table id="myTable">
<tr>
<td>Row 1</td>
</tr>
<tr>
<td>Row 2</td>
</tr>
<tr>
<td>Row 3</td>
</tr>
<tr>
<td>Row 4</td>
</tr>
<tr>
<td>Row 5</td>
</tr>
</table>
<input type="button" value="Delete Rows">
因为现在可以在 NodeList
上调用 forEach
数组方法。我想知道为什么如果您在使用 forEach
循环时更改 childNodes
NodeList 的内容,forEach
不会检测到更改。
grid.childNodes.forEach(function(tableRow, index, nodeList) {
tableRow.remove();
});
在这里,我试图遍历我的 table(grid) 子元素并从 table 中删除每个子元素 (tableRow
)。但是,forEach
永远不会完全遍历每个元素,总是遗漏最后一个 tableRow
是 remove
d.I 认为它与 childNodes NodeList 正在运行有关,并且forEach 无法正确地遵循它或其他东西。
这是因为,在较低的级别上,.forEach()
仍在保持计数并使用元素的索引。当您删除一些时,您是从 array/node 列表的开头删除它们,然后索引器变得不准确,因为所有元素索引都必须向下移动一个。例如,曾经位于索引位置 5 的元素现在位于索引位置 4。
对于这样的事情,最好使用计数循环并从最后一个索引开始并向后工作删除元素。这将在循环期间保持适当的计数,因为不会修改元素到索引的映射。
这是一个例子:
let grid = document.getElementById("myTable");
document.querySelector("input").addEventListener("click", function(){
for(i = grid.childNodes.length-1; i > -1; i--) {
grid.removeChild(grid.childNodes[i]);
}
});
<table id="myTable">
<tr>
<td>Row 1</td>
</tr>
<tr>
<td>Row 2</td>
</tr>
<tr>
<td>Row 3</td>
</tr>
<tr>
<td>Row 4</td>
</tr>
<tr>
<td>Row 5</td>
</tr>
</table>
<input type="button" value="Delete Rows">
现在,如果您要使用 DOM Table API and .deleteRow()
let grid = document.getElementById("myTable");
document.querySelector("input").addEventListener("click", function(){
for(i = grid.rows.length-1; i > -1; i--) {
grid.deleteRow(i);
}
});
<table id="myTable">
<tr>
<td>Row 1</td>
</tr>
<tr>
<td>Row 2</td>
</tr>
<tr>
<td>Row 3</td>
</tr>
<tr>
<td>Row 4</td>
</tr>
<tr>
<td>Row 5</td>
</tr>
</table>
<input type="button" value="Delete Rows">
当然,您可以通过清除 .innerHTML
.
let grid = document.getElementById("myTable");
document.querySelector("input").addEventListener("click", function(){
grid.innerHTML = "";
});
<table id="myTable">
<tr>
<td>Row 1</td>
</tr>
<tr>
<td>Row 2</td>
</tr>
<tr>
<td>Row 3</td>
</tr>
<tr>
<td>Row 4</td>
</tr>
<tr>
<td>Row 5</td>
</tr>
</table>
<input type="button" value="Delete Rows">