我想迭代一些DOM元素,我这样做:
document.getElementsByClassName( "myclass" ).forEach( function(element, index, array) {
//do stuff
});
但是我收到一个错误:document.getElementsByClassName(“myclass”)。forEach不是函数
我使用的是Firefox 3,因此我知道getElementsByClassName
和Array.forEach
都存在。这很好用:
[2, 5, 9].forEach( function(element, index, array) {
//do stuff
});
getElementsByClassName
数组的结果是?如果没有,那是什么?
答案 0 :(得分:279)
没有。作为specified in 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的幸福位置(即您可以放心地忽略Internet Explorer或使用ES5转换程序),则可以使用Array.from
:
Array.from(els).forEach((el) => {
// Do stuff here
console.log(el.tagName);
});
答案 1 :(得分:55)
您可以使用'44'
将集合转换为数组,这比Array.from
更清晰:
Array.prototype.forEach.call
在不支持Array.from(document.getElementsByClassName("myclass")).forEach(
function(element, index, array) {
// do stuff
}
);
的旧浏览器中,您需要使用像Babel这样的内容。
ES6还添加了这种语法:
Array.from
使用[...document.getElementsByClassName("myclass")].forEach(
(element, index, array) => {
// do stuff
}
);
进行休息解构可以处理所有类似数组的对象,而不仅仅是数组本身,然后使用旧的数组语法从值构造数组。
虽然替代函数...
(使querySelectorAll
过时)返回一个本身具有getElementsByClassName
的集合,但其他方法如forEach
或map
缺少,所以这种语法仍然有用:
filter
答案 2 :(得分:15)
或者您可以使用返回NodeList的querySelectorAll
:
document.querySelectorAll('.myclass').forEach(...)
现代浏览器支持(包括Edge,但不支持IE):
Can I use querySelectorAll
NodeList.prototype.forEach()
答案 3 :(得分:13)
编辑:虽然新版本的HTML中的返回类型已更改(请参阅Tim Down的更新答案),但以下代码仍然有效。
正如其他人所说,它是一个NodeList。这是一个完整的,可以尝试的工作示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script>
function findTheOddOnes()
{
var theOddOnes = document.getElementsByClassName("odd");
for(var i=0; i<theOddOnes.length; i++)
{
alert(theOddOnes[i].innerHTML);
}
}
</script>
</head>
<body>
<h1>getElementsByClassName Test</h1>
<p class="odd">This is an odd para.</p>
<p>This is an even para.</p>
<p class="odd">This one is also odd.</p>
<p>This one is not odd.</p>
<form>
<input type="button" value="Find the odd ones..." onclick="findTheOddOnes()">
</form>
</body>
</html>
这适用于Win 7上的IE 9,FF 5,Safari 5和Chrome 12。
答案 4 :(得分:5)
getElementsByClassName的结果是否为数组?
没有
如果没有,那是什么?
与返回多个元素的所有DOM方法一样,它是一个NodeList,请参阅https://developer.mozilla.org/en/DOM/document.getElementsByClassName
答案 5 :(得分:5)
getElementsByClassName()
的结果不是数组,而是类数组对象。具体来说,它被称为HTMLCollection
,不要与NodeList
(which has it's own forEach()
method)混淆。
使用ES2015转换类似数组的对象以便与Array.prototype.forEach()
一起使用尚未提及的一种简单方法是使用扩展运算符或spread syntax:
const elementsArray = document.getElementsByClassName('myclass');
[...elementsArray].forEach((element, index, array) => {
// do something
});
答案 6 :(得分:3)
如上所述,getElementsByClassName
返回HTMLCollection,定义为
[Exposed=Window]
interface HTMLCollection {
readonly attribute unsigned long length;
getter Element? item(unsigned long index);
getter Element? namedItem(DOMString name);
};
以前,有些浏览器会返回NodeList。
[Exposed=Window]
interface NodeList {
getter Node? item(unsigned long index);
readonly attribute unsigned long length;
iterable<Node>;
};
区别很重要,因为DOM4现在将 NodeList 定义为可迭代的。
根据Web IDL草案,
实现声明为可迭代的接口的对象 支持迭代以获得一系列值。
注意:在ECMAScript语言绑定中,是一个接口 iterable将具有“entries”,“forEach”,“keys”,“values”和 @@iterator上的interface prototype object属性。
这意味着,如果您想使用forEach
,您可以使用返回 NodeList 的DOM方法,例如querySelectorAll
。
document.querySelectorAll(".myclass").forEach(function(element, index, array) {
// do stuff
});
请注意,目前尚未得到广泛支持。另请参阅forEach method of Node.childNodes?
答案 7 :(得分:0)
它不返回Array
,而是返回NodeList。
答案 8 :(得分:0)
这是更安全的方法:
var elements = document.getElementsByClassName("myclass");
for (var i = 0; i < elements.length; i++) myFunction(elements[i]);
答案 9 :(得分:0)
getElementsByClassName
在现代浏览器中返回 HTMLCollection 。
这是
类似于自变量的类似于数组的对象,可以通过for...of
循环对其进行迭代,请参见下面的MDN文档所说的内容:
for ... of语句创建一个循环遍历可迭代对象, 包括:内置String,Array,类似数组的对象(例如,参数 或NodeList),TypedArray,Map,Set和用户定义的可迭代对象。它 调用一个自定义迭代钩子,该钩子要为 对象的每个不同属性的值。
示例
for (let element of getElementsByClassName("classname")){
element.style.display="none";
}
答案 10 :(得分:0)
这是我在jsperf上创建的测试: https://jsperf.com/vanillajs-loop-through-elements-of-class
Chrome和Firefox中性能最好的版本是结合document.getElementsByClassName的旧版本for循环:
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';
}
);