使用 Array.forEach 迭代 getElementsByClassName 的结果
我想迭代一些 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
的结果是一个数组吗?如果不是,那是什么?
I want to iterate over some DOM elements, I'm doing this:
document.getElementsByClassName( "myclass" ).forEach( function(element, index, array) {
//do stuff
});
but I get an error:
document.getElementsByClassName("myclass").forEach is not a function
I am using Firefox 3 so I know that both getElementsByClassName
and Array.forEach
are present. This works fine:
[2, 5, 9].forEach( function(element, index, array) {
//do stuff
});
Is the result of getElementsByClassName
an Array? If not, what is it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
不,这不是一个数组。正如 在 DOM4 中指定的,它是一个
HTMLCollection
(至少在现代浏览器中。旧版浏览器返回NodeList
)。在所有现代浏览器(几乎任何其他 IE <= 8)中,您可以调用 Array 的
forEach
方法,向其传递元素列表(无论是HTMLCollection
还是NodeList
) 作为this
值:如果您很高兴能够使用 ES6(即您可以安全地忽略 Internet Explorer 或者您正在使用 ES5 转译器) ,您可以使用
Array.from< /代码>
:
No, it's not an array. As specified in DOM4, it's an
HTMLCollection
(in modern browsers, at least. Older browsers returned aNodeList
).In all modern browsers (pretty much anything other IE <= 8), you can call Array's
forEach
method, passing it the list of elements (be itHTMLCollection
orNodeList
) as thethis
value:If you're in the happy position of being able to use ES6 (i.e. you can safely ignore Internet Explorer or you're using an ES5 transpiler), you can use
Array.from
:您可以使用 Array.from 将集合转换为数组,这比 Array.prototype.forEach.call 更干净:
在不支持
的旧版浏览器中Array.from
,你需要使用Babel之类的东西。ES6 还添加了此语法:
使用
...
进行剩余解构适用于所有类似数组的对象,而不仅仅是数组本身,然后使用良好的旧数组语法从值构造数组。虽然替代函数
querySelectorAll
(这有点使得getElementsByClassName
过时)返回一个本身具有forEach
的集合,但其他方法如map< /code> 或
filter
丢失,因此此语法仍然有用:You can use
Array.from
to convert collection to array, which is way cleaner thanArray.prototype.forEach.call
:In older browsers which don't support
Array.from
, you need to use something like Babel.ES6 also adds this syntax:
Rest destructuring with
...
works on all array-like objects, not only arrays themselves, then good old array syntax is used to construct an array from the values.While the alternative function
querySelectorAll
(which kinda makesgetElementsByClassName
obsolete) returns a collection which does haveforEach
natively, other methods likemap
orfilter
are missing, so this syntax is still useful:或者您可以使用
querySelectorAll
,它返回 NodeList:现代浏览器支持(包括Edge,但不支持IE):
我可以使用 querySelectorAll
NodeList.prototype.forEach()
MDN: Document.querySelectorAll()
Or you can use
querySelectorAll
which returns NodeList:Supported by modern browsers (including Edge, but not IE):
Can I use querySelectorAll
NodeList.prototype.forEach()
MDN: Document.querySelectorAll()
getElementsByClassName()
的结果不是一个数组,而是一个类似数组的对象。具体来说,它称为HTMLCollection
,不要与NodeList
混淆(它有自己的forEach()
方法)。使用 ES2015 转换类数组对象以便与 Array.prototype.forEach() 一起使用的一种简单方法(尚未提及)是使用展开运算符或 传播语法:
The result of
getElementsByClassName()
is not an Array, but an array-like object. Specifically it's called anHTMLCollection
, not to be confused withNodeList
(which has it's ownforEach()
method).One simple way with ES2015 to convert an array-like object for use with
Array.prototype.forEach()
that hasn't been mentioned yet is to use the spread operator or spread syntax:getElementsByClassName
在现代浏览器中返回 HTMLCollection。这是
类似于参数的数组对象,可通过
for...of
循环进行迭代,请参阅下面的内容MDN 文档对此是这么说的:Javascript 示例
Typescript 示例
getElementsByClassName
returns HTMLCollection in modern browsers.which is
array-like object similar to arguments which is iteratable by
for...of
loop see below what MDN doc is saying about it:Javascript Example
Typescript Example
编辑:尽管新版本的 HTML 中的返回类型已更改(请参阅 Tim Down 的更新答案),但下面的代码仍然有效。
正如其他人所说,它是一个 NodeList。这是一个完整的、有效的示例,您可以尝试:
这适用于 Win 7 上的 IE 9、FF 5、Safari 5 和 Chrome 12。
Edit: Although the return type has changed in new versions of HTML (see Tim Down's updated answer), the code below still works.
As others have said, it's a NodeList. Here's a complete, working example you can try:
This works in IE 9, FF 5, Safari 5, and Chrome 12 on Win 7.
对于打字稿,我更喜欢迭代
for typescript I prefer iterating for
如前所述,
getElementsByClassName
返回一个 HTMLCollection,其定义为以前,某些浏览器返回 NodeList< /em> 相反。
区别很重要,因为 DOM4 现在将 NodeList 定义为可迭代的。
根据 Web IDL 草案,
这意味着,如果您想使用
forEach
,您可以使用返回 NodeList 的 DOM 方法,例如querySelectorAll
。请注意,这尚未得到广泛支持。另请参阅 Node.childNodes 的 forEach 方法?
As already said,
getElementsByClassName
returns a HTMLCollection, which is defined asPreviously, some browsers returned a NodeList instead.
The difference is important, because DOM4 now defines NodeLists as iterable.
According to Web IDL draft,
That means that, if you want to use
forEach
, you can use a DOM method which returns a NodeList, likequerySelectorAll
.Note this is not widely supported yet. Also see forEach method of Node.childNodes?
不
与所有返回多个元素的 DOM 方法一样,它是一个 NodeList,请参阅 https:// developer.mozilla.org/en/DOM/document.getElementsByClassName
No
As with all DOM methods that return multiple elements, it is a NodeList, see https://developer.mozilla.org/en/DOM/document.getElementsByClassName
这是更安全的方法:
This is the safer way:
最简单的解决方案:
之后你可以这样写:
The simplest solution:
After that you can write like this:
????
这是我在 jsperf 上创建的测试:
https://jsperf.com/vanillajs-loop-through-elements-of- class
Chrome 和 Firefox 中性能最好的版本是旧的 for 循环与 document.getElementsByClassName 的结合:
在 Safari 中,这个变体是赢家:
如果您想要所有浏览器中性能最好的变体,它可能是这个:
Here is a test I created on jsperf:
https://jsperf.com/vanillajs-loop-through-elements-of-class
The most perfomant version in Chrome and Firefox is the good old for loop in combination with document.getElementsByClassName:
In Safari this variant is the winner:
If you want the most perfomant variant for all browsers it might be this one:
使用此代码将 forEach 方法添加到 HTMLCollection
然后您的代码将起作用:
Use this code to add forEach method to HTMLCollection
Then your code will work:
它不返回
Array
,而是返回NodeList。It does not return an
Array
, it returns a NodeList.