我想迭代一些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的结果是数组吗?如果不是,是什么?
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);
});
下面是我在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,它被定义为
[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属性。
这意味着,如果你想使用forEach,你可以使用一个返回节点列表的DOM方法,比如querySelectorAll。
document.querySelectorAll(".myclass").forEach(function(element, index, array) {
// do stuff
});
注意,这还没有得到广泛支持。另见Node.childNodes?