在循环 HTMLCollection 时包装元素会导致问题
Wrapping elements while looping through HTMLCollection causes problem
我想将容器中的每个项目包装在 div 中。当我遍历 HTMLCollection 时,某些元素被多次访问而其他元素被遗漏
HTML
<div class="container">
<div class="item_1"></div>
<div class="item_2"></div>
<div class="item_3"></div>
<div class="item_4"></div>
<div class="item_5"></div>
<div class="item_6"></div>
<div class="item_7"></div>
<div class="item_8"></div>
<div class="item_9"></div>
</div>
JS
const container = document.querySelector('.container');
const items = container.children;
for(let i = 0; i < items.length; i++) {
const wrapper = document.createElement('div');
wrapper.classList.add('wrapper');
wrapper.appendChild(items[i]);
container.appendChild(wrapper);
}
直接循环 HTMLCollection 给出了这个奇怪的结果
<div class="container">
<div class="item_2"></div>
<div class="item_4"></div>
<div class="item_6"></div>
<div class="item_8"></div>
<div class="wrapper">
<div class="item_1"></div>
</div>
<div class="wrapper">
<div class="item_5"></div>
</div>
<div class="wrapper">
<div class="item_9"></div>
</div>
<div class="wrapper">
<div class="wrapper">
<div class="item_7"></div>
</div>
</div>
<div class="wrapper">
<div class="wrapper">
<div class="wrapper">
<div class="wrapper">
<div class="item_3"></div>
</div>
</div>
</div>
</div>
</div>
当我将 HTMLCollection 转换为 Array
时问题得到解决
const items = Array.from(container.children);
我不明白是什么导致了这种行为
您正在迭代 container.children
列表,您也在迭代期间更改了该列表。这搞砸了迭代。正如您自己提到的,您可以通过将 container.children
转换为数组来解决此问题,因为这样您就不会遍历实时 container.children
列表,而是遍历它的数组副本。此副本仍引用正确的子元素,因此可以使用 appendChild()
函数正确移动它们。
作为替代方法,您可以使用 querySelecterAll()
来检索您想要包装的所有元素。
const container = document.querySelector('.container');
const items = container.querySelectorAll('.container > *');
for(let i = 0; i < items.length; i++) {
const wrapper = document.createElement('div');
wrapper.classList.add('wrapper');
wrapper.appendChild(items[i]);
container.appendChild(wrapper);
}
.wrapper {
background-color: red;
}
<div class="container">
<div class="item_1">1</div>
<div class="item_2">2</div>
<div class="item_3">3</div>
<div class="item_4">4</div>
<div class="item_5">5</div>
<div class="item_6">6</div>
<div class="item_7">7</div>
<div class="item_8">8</div>
<div class="item_9">9</div>
</div>
我想将容器中的每个项目包装在 div 中。当我遍历 HTMLCollection 时,某些元素被多次访问而其他元素被遗漏
HTML
<div class="container">
<div class="item_1"></div>
<div class="item_2"></div>
<div class="item_3"></div>
<div class="item_4"></div>
<div class="item_5"></div>
<div class="item_6"></div>
<div class="item_7"></div>
<div class="item_8"></div>
<div class="item_9"></div>
</div>
JS
const container = document.querySelector('.container');
const items = container.children;
for(let i = 0; i < items.length; i++) {
const wrapper = document.createElement('div');
wrapper.classList.add('wrapper');
wrapper.appendChild(items[i]);
container.appendChild(wrapper);
}
直接循环 HTMLCollection 给出了这个奇怪的结果
<div class="container">
<div class="item_2"></div>
<div class="item_4"></div>
<div class="item_6"></div>
<div class="item_8"></div>
<div class="wrapper">
<div class="item_1"></div>
</div>
<div class="wrapper">
<div class="item_5"></div>
</div>
<div class="wrapper">
<div class="item_9"></div>
</div>
<div class="wrapper">
<div class="wrapper">
<div class="item_7"></div>
</div>
</div>
<div class="wrapper">
<div class="wrapper">
<div class="wrapper">
<div class="wrapper">
<div class="item_3"></div>
</div>
</div>
</div>
</div>
</div>
当我将 HTMLCollection 转换为 Array
时问题得到解决const items = Array.from(container.children);
我不明白是什么导致了这种行为
您正在迭代 container.children
列表,您也在迭代期间更改了该列表。这搞砸了迭代。正如您自己提到的,您可以通过将 container.children
转换为数组来解决此问题,因为这样您就不会遍历实时 container.children
列表,而是遍历它的数组副本。此副本仍引用正确的子元素,因此可以使用 appendChild()
函数正确移动它们。
作为替代方法,您可以使用 querySelecterAll()
来检索您想要包装的所有元素。
const container = document.querySelector('.container');
const items = container.querySelectorAll('.container > *');
for(let i = 0; i < items.length; i++) {
const wrapper = document.createElement('div');
wrapper.classList.add('wrapper');
wrapper.appendChild(items[i]);
container.appendChild(wrapper);
}
.wrapper {
background-color: red;
}
<div class="container">
<div class="item_1">1</div>
<div class="item_2">2</div>
<div class="item_3">3</div>
<div class="item_4">4</div>
<div class="item_5">5</div>
<div class="item_6">6</div>
<div class="item_7">7</div>
<div class="item_8">8</div>
<div class="item_9">9</div>
</div>