我想迭代一些DOM元素,我这样做:

document.getElementsByClassName( "myclass" ).forEach( function(element, index, array) {
  //do stuff
});

但是我得到了一个错误:

document.getElementsByClassName(“myclass”)。forEach不是一个函数

我使用Firefox 3,所以我知道getElementsByClassName和Array。每个人都在场。这很好:

[2, 5, 9].forEach( function(element, index, array) {
  //do stuff
});

getElementsByClassName的结果是数组吗?如果不是,是什么?


当前回答

不,它不是数组。正如DOM4中指定的那样,它是一个HTMLCollection(至少在现代浏览器中是这样)。旧的浏览器返回一个NodeList)。

在所有现代浏览器(几乎所有其他IE <= 8)中,你可以调用Array的forEach方法,将元素列表(无论是HTMLCollection还是NodeList)作为this值传递给它:

var els = document.getElementsByClassName("myclass");

Array.prototype.forEach.call(els, function(el) {
    // Do stuff here
    console.log(el.tagName);
});

// Or
[].forEach.call(els, function (el) {...});

如果你很高兴能够使用ES6(即你可以安全地忽略ie或你正在使用ES5转译器),你可以使用Array.from:

Array.from(els).forEach((el) => {
    // Do stuff here
    console.log(el.tagName);
});

其他回答

它不返回数组,而是返回节点列表。

下面是我在jsperf上创建的一个测试: https://jsperf.com/vanillajs-loop-through-elements-of-class

Chrome和Firefox中性能最好的版本是旧的for循环结合document.getElementsByClassName:

var elements = document.getElementsByClassName('testClass'), elLength = elements.length;
for (var i = 0; i < elLength; i++) {
    elements.item(i).textContent = 'Tested';
};

在Safari中,这个变体是赢家:

var elements = document.querySelectorAll('.testClass');
elements.forEach((element) => {
    element.textContent = 'Tested';
});

如果你想要所有浏览器的性能最好的变体,它可能是这个:

var elements = document.getElementsByClassName('testClass');
Array.from(elements).map(
    (element) => {
        return element.textContent = 'Tested';
    }
);

getElementsByClassName()的结果不是数组,而是一个类数组对象。具体来说,它被称为HTMLCollection,不要与NodeList混淆(NodeList有自己的forEach()方法)。

在ES2015中,一个简单的方法是将一个类数组对象转换为Array.prototype.forEach(),这个方法还没有提到,就是使用spread操作符或spread语法:

const elementsArray = document.getElementsByClassName('myclass');

[...elementsArray].forEach((element, index, array) => {
    // do something
});

getElementsByClassName在现代浏览器中返回HTMLCollection。

这是 类似数组的对象,类似于参数,可通过for…查看下面MDN文档是怎么说的:

为…语句Of创建了一个遍历可迭代对象的循环, 包括:内置字符串,数组,数组类对象(例如,参数 或NodeList), TypedArray, Map, Set和用户定义的迭代对象。它 类要执行的语句调用自定义迭代钩子 对象的每个不同属性的值。

Javascript的例子

for (const element of document.getElementsByClassName("classname")){
   element.style.display="none";
}

打印稿的例子

let elements = document.getElementsByClassName('classname');
let i;

for (i = 0; i < elements.length; i++) {

  if (elements[i] instanceof HTMLElement) {
    elements[i].style.display = "none";
  }

}

不,它不是数组。正如DOM4中指定的那样,它是一个HTMLCollection(至少在现代浏览器中是这样)。旧的浏览器返回一个NodeList)。

在所有现代浏览器(几乎所有其他IE <= 8)中,你可以调用Array的forEach方法,将元素列表(无论是HTMLCollection还是NodeList)作为this值传递给它:

var els = document.getElementsByClassName("myclass");

Array.prototype.forEach.call(els, function(el) {
    // Do stuff here
    console.log(el.tagName);
});

// Or
[].forEach.call(els, function (el) {...});

如果你很高兴能够使用ES6(即你可以安全地忽略ie或你正在使用ES5转译器),你可以使用Array.from:

Array.from(els).forEach((el) => {
    // Do stuff here
    console.log(el.tagName);
});