我想迭代一些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的结果是数组吗?如果不是,是什么?


当前回答

你可以使用array .from将集合转换为数组,这比array .prototype. foreach .call干净得多:

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

在不支持Array.from的旧浏览器中,您需要使用Babel之类的东西。


ES6还添加了以下语法:

[...document.getElementsByClassName("myclass")].forEach(
    (element, index, array) => {
        // do stuff
    }
);

其余的解构…适用于所有类数组对象,而不仅仅是数组本身,然后使用良好的旧数组语法从值构造数组。


虽然替代函数querySelectorAll(这有点使getElementsByClassName过时)返回一个原生具有forEach的集合,但其他方法如map或filter都没有,所以这个语法仍然有用:

[...document.querySelectorAll(".myclass")].map(
    (element, index, array) => {
        // do stuff
    }
);

[...document.querySelectorAll(".myclass")].map(element => element.innerHTML);

其他回答

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

for typescript,我更喜欢迭代

for(let element of Array.from(document.querySelectorAll('.myclass'))){
   //my code
}

getElementsByClassName的结果是数组吗?

No

如果不是,是什么?

与所有返回多个元素的DOM方法一样,它是一个NodeList,参见https://developer.mozilla.org/en/DOM/document.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);
});

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

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

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

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