JavaScript .children循环时的HTML集合长度问题

JavaScript .children HTML collection length issues when looping

本文关键字:集合 问题 HTML children 循环 JavaScript      更新时间:2023-09-26

我正在尝试循环使用以下代码从JavaScript的.children属性产生的HTMLCollection:

var articles = data.children;
var newsGrid = document.getElementById('js-news__grid');
for (var i = 0; i < articles.length; i++) {
   articles[i].classList.add('loading');
   newsGrid.appendChild(articles[i]);
};

data变量是一个成功的XHR的片段。当我运行循环时,它只附加第一个子元素和循环结束,当在循环之前运行console.log(articles);时,它显示2个HTML元素(就像它应该的那样),但只有1的长度。如果我删除循环并运行console.log(articles);,它会像以前一样显示2个HTML元素,但现在它的长度为2。

为了简单起见,我省略了XHR代码,因为HTMLCollection是由数据生成的。孩子看起来是对的。以下是日志信息:

[article.news__item, article.news__item]
0: article.news__item
1: article.news__item
length: 2
__proto__: HTMLCollection
[article.news__item, article.news__item]
0: article.news__item
length: 1
__proto__: HTMLCollection

问题是。children是一个活动集合,当您将每个子元素移出容器时,它将被更新。

在你的例子中,data有2个子元素,所以当循环开始时,articles.length是2,但是在第一次迭代之后,你重新定位了第一个子元素,这意味着articles对象现在只包含1个元素,i是2,现在循环条件i < articles.length失败。

一个简单的解决方案是使用反向循环

var articles = data.children;
var newsGrid = document.getElementById('js-news__grid');
for (var i = articles.length - 1; i >= 0; i--) {
    articles[i].classList.add('loading');
    newsGrid.appendChild(articles[i]);
};

另一个解决方案是将articles转换为普通数组

var articles = [].slice.call(data.children);

RobG建议的另一种方法是
var articles = data.children;
var newsGrid = document.getElementById('js-news__grid');
while (articles.length) {
    articles[0].classList.add('loading');
    newsGrid.appendChild(articles[0]);
};