首页 > 解决方案 > 循环遍历 HTMLCollection 时包装元素会导致问题

问题描述

我想将容器的每个项目包装在一个 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 转换为数组时问题得到解决

const items = Array.from(container.children);

我不明白是什么导致了这种行为

标签: javascripthtmlloopshtmlcollection

解决方案


您正在迭代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>


推荐阅读