为什么每个不为儿童工作?

时间:2013-02-26 16:58:59

标签: javascript for-loop foreach parent-child

我有一个<div>,里面有一些孩子<div>。 E.g。

<div id="niceParent">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

我尝试使用forEach函数循环遍历它们,因为我认为document.getElementById("niceParent").children是一个数组,因为我可以使用

访问元素
console.log(document.getElementById("niceParent").children[1]);
console.log(document.getElementById("niceParent").children[2]);
console.log(document.getElementById("niceParent").children[3]);
console.log(document.getElementById("niceParent").children[4]);

因此我尝试了

document.getElementById("niceParent").children.forEach(function(entry) {
  console.log(entry);
});

哪个不行。我得到了

TypeError: document.getElementById(...).children.forEach is not a function

作为一种解决方法,我还尝试了一个更复杂的问题 - for..in循环:

for (var i in document.getElementById("niceParent").children) {
  if (document.getElementById("niceParent").children[i].nodeType == 1) console.log(document.getElementById("niceParent").children[i]);
}

按预期工作。

为什么?

6 个答案:

答案 0 :(得分:40)

因为.children包含NodeList [MDN],而不是数组。 NodeList对象是类似数组的对象,它公开.length属性并具有数字属性,只是类似数组,但它没有继承自Array.prototype,因此不是数组。

您可以使用Array.prototype.slice将其转换为数组:

var children = [].slice.call(document.getElementById(...).children);

ECMAScript 6 引入了一个新的API,用于将迭代器和类似数组的对象转换为实数数组:Array.from [MDN]。如果可能的话使用它,因为它使意图更加清晰。

var children = Array.from(document.getElementById(...).children);

答案 1 :(得分:9)

Element.children 数组。它是一个名为HTMLCollection的对象。它们没有数组的方法(尽管它们具有length属性)。

要遍历它,您必须将其转换为数组,您可以使用Array.prototype.slice执行此操作:

var children = Array.prototype.slice.call(document.getElementById("niceParent").children);

children.forEach(…);

答案 2 :(得分:2)

你也可以这样做:

NodeList.prototype.forEach = HTMLCollection.prototype.forEach = Array.prototype.forEach;

在此之后,你可以在你的收藏中打电话给每个人:

document.getElementById("niceParent").children.forEach(...)

最好和最安全的方法实际上只是在尚不存在的情况下添加forEach:

if (window.NodeList && !NodeList.prototype.forEach) {
   NodeList.prototype.forEach = Array.prototype.forEach;
}
if (window.HTMLCollection && !HTMLCollection.prototype.forEach) {
   HTMLCollection.prototype.forEach = Array.prototype.forEach;
}

答案 3 :(得分:1)

HTMLCollection之类的.children转换为数组以使用forEach()(或map()等)的一种更简洁,更现代的方法是使用{{ 3}}在数组[]中。

var children = [...document.getElementById('x').children)];

例如:

[...document.getElementById('x').children)].forEach(child => console.log(child))

这是es6功能。它将在所有现代浏览器上运行。

答案 4 :(得分:0)

如果您需要使用轻量级npm模块的干净方法来解决上述问题,请查看https://www.npmjs.com/package/foreach-array

例如:

import each from 'foreach-array';

const array = ['First Name', 'Last Name', 'Country'];

each(array, (value, index, array) => {
    console.log(index + ': ' + value);
});

// Console log output will be:
//      0: First Name
//      1: Last Name
//      2: Country

在您的情况下,它是document.getElementById("niceParent").children,而不是上面示例中的array

答案 5 :(得分:0)

也许这是一个简单的解决方案:

document.getElementById("niceParent").childNodes.forEach(function(entry) {
  console.log(entry);
});