49

我有一个<div>孩子<div>在里面。例如

<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

作为一种解决方法,我还尝试了一个更复杂的 <code>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]);
}

按预期工作。

为什么?

4

6 回答 6

75

因为.children包含HTMLCollection [MDN],而不是数组。HTMLCollection对象是一个类数组对象,它公开一个.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);
于 2013-02-26T17:00:50.500 回答
12

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

要遍历它,您必须将其转换为数组,您可以使用Array.prototype.slice

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

children.forEach(…);
于 2013-02-26T17:01:16.973 回答
11

HTMLCollection将like转换为.children要使用的数组forEach()(或map()等)的一种更简洁、更现代的方法是在数组中使用扩展语法...[]

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

例如:

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

这是 es6 的一个特性。它适用于所有现代浏览器。

[...document.getElementById('niceParent').children].forEach(child => console.log(child.textContent))
<div id="niceParent">
  <div>a</div>
  <div>b</div>
  <div>c</div>
  <div>d</div>
</div>

于 2018-09-19T09:59:26.490 回答
2

你也可以这样做:

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

在此之后,您可以在您的收藏中调用 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;
}
于 2013-02-26T17:08:27.273 回答
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上面的示例

于 2020-11-03T00:35:56.300 回答
0

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

document.getElementById("niceParent").childNodes.forEach(function(entry) {
  console.log(entry);
});
于 2021-05-27T19:57:18.260 回答