为何将tableBody.children(HTMLCollection)转为数组时返回空数组?
问题
尝试将tableBody.children(HTMLCollection)转换为数组以进行遍历,使用Array.from(tableBody.children)并赋值给变量tableChildren,但调用该变量时返回空数组。奇怪的是,如果移除Array.from,直接const tableChildren = tableBody.children能得到完整的HTMLCollection,但加上Array.from后就变成空数组。
完整代码如下:
function editFormSubmit(tableBody) { const dogForm = document.getElementById("dog-form"); // 有问题的变量 const tableChildren = Array.from(tableBody.children); dogForm.addEventListener("submit", event => { event.preventDefault(); const updatedDog = { name: event.target[0].value, breed: event.target[1].value, sex: event.target[2].value } fetch(`http://localhost:3000/dogs/${event.target[3].value}`, { method: "PATCH", headers: { "Content-Type": "application/json", Accept: "application/json" }, body: JSON.stringify(updatedDog) }) .then(res => res.json()) .then(dog => { tableBody.textContent = ""; getDogs(tableBody); // 调用变量的位置 console.log(tableChildren); }) .catch(err => console.log(err)) }) }
解答
问题核心在于变量赋值时机和HTMLCollection的特性差异:
HTMLCollection是实时动态集合,直接赋值const tableChildren = tableBody.children时,变量指向的是DOM的实时状态——哪怕后续tableBody内容被清空重建,调用它时都会重新读取当前DOM,所以能拿到完整内容。Array.from(tableBody.children)是一次性快照,它在函数执行(绑定事件监听)的瞬间就把当时tableBody的子元素转换成了数组。如果此时表格还没通过getDogs加载内容,生成的数组自然是空的。- 你在
fetch回调里才打印tableChildren,但这个变量早在事件绑定阶段就固定了,后续DOM的变化不会影响这个已经生成的数组。
解决办法:
把Array.from(tableBody.children)的赋值移到需要使用它的时机:
- 如果要获取更新前的表格子元素,就放在清空
tableBody之前:.then(dog => { // 先获取当前子元素的数组快照 const tableChildren = Array.from(tableBody.children); console.log(tableChildren); // 再执行清空和重建操作 tableBody.textContent = ""; getDogs(tableBody); }) - 如果要获取更新后的表格子元素,需确保在
getDogs完成后再执行数组转换(若getDogs是异步操作,要等待其完成)。
内容的提问来源于stack exchange,提问作者Christian Lopez
相关产品推荐
相关产品推荐

