在循环 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>