我正在尝试使用以下代码遍历从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代码,因为从data.children生成的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
答案 0 :(得分:2)
问题是.children是一个实时集合,当您将每个孩子移出容器时,它会更新。
在您的情况下,data
有2个子项,因此在启动循环时articles.length
为2,但在第一次迭代后您重新定位了第一个子项,这意味着articles
object现在只包含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]);
};