本文翻译自:For loop for HTMLCollection elements

I'm trying to set get id of all elements in an HTMLCollectionOf . 我正在尝试设置HTMLCollectionOf中所有元素的获取ID。 I wrote the following code: 我写了以下代码:

var list = document.getElementsByClassName("events");
console.log(list[0].id);
for (key in list) {console.log(key.id);
}

But I got the following output in console: 但是我在控制台中得到以下输出:

event1
undefined

which is not what I expected. 这不是我所期望的。 Why is the second console output undefined but the first console output is event1 ? 为什么第二个控制台输出undefined但第一个控制台输出是event1


#1楼

参考:https://stackoom.com/question/1XTR5/HTMLCollection元素的For循环


#2楼

You want to change it to 您想要将其更改为

var list= document.getElementsByClassName("events");
console.log(list[0].id); //first console output
for (key in list){console.log(list[key].id); //second console output
}

#3楼

In response to the original question, you are using for/in incorrectly. 在回答原始问题时,您使用for/in不正确的for/in In your code, key is the index. 在您的代码中, key是索引。 So, to get the value from the pseudo-array, you'd have to do list[key] and to get the id, you'd do list[key].id . 因此,要从伪数组中获取值,您必须执行list[key]并获取ID,您必须执行list[key].id But, you should not be doing this with for/in in the first place. 但是,您不应该首先使用for/in进行此操作。

Summary (added in Dec 2018) 摘要(于2018年12月新增)

Do not ever use for/in to iterate a nodeList or an HTMLCollection. 永远不要使用for/in来迭代nodeList或HTMLCollection。 The reasons to avoid it are described below. 避免这种情况的原因如下所述。

All recent versions of modern browsers (Safari, Firefox, Chrome, Edge) all support for/of iteration on DOM lists such nodeList or HTMLCollection . 现代浏览器的所有最新版本(Safari,Firefox,Chrome,Edge)都支持DOM列表上for/of迭代,例如nodeListHTMLCollection

Here's an example: 这是一个例子:

var list = document.getElementsByClassName("events");
for (let item of list) {console.log(item.id);
}

To include older browsers (including things like IE), this will work everywhere: 要包括较旧的浏览器(包括IE之类的东西),它将在任何地方都适用:

var list= document.getElementsByClassName("events");
for (var i = 0; i < list.length; i++) {console.log(list[i].id); //second console output
}

Explanation For Why You Should Not Use for/in 为什么不应该for/in使用的解释

for/in is meant for iterating the properties of an object. for/in用于迭代对象的属性。 That means it will return all iterable properties of an object. 这意味着它将返回对象的所有可迭代属性。 While it may appear to work for an array (returning array elements or pseudo-array elements), it can also return other properties of the object that are not what you are expecting from the array-like elements. 尽管它似乎可以用于数组(返回数组元素或伪数组元素),但它也可以返回对象的其他属性,这些属性不是您希望从类似数组的元素中获得的。 And, guess what, an HTMLCollection or nodeList object can both have other properties that will be returned with a for/in iteration. 而且,猜想是什么, HTMLCollectionnodeList对象都可以具有其他属性,这些属性将通过for/in迭代返回。 I just tried this in Chrome and iterating it the way you were iterating it will retrieve the items in the list (indexes 0, 1, 2, etc...), but also will retrieve the length and item properties. 我只是在Chrome中尝试了此操作,然后以您迭代的方式对其进行了迭代,它将检索列表中的项目(索引0、1、2等...),但还将检索lengthitem属性。 The for/in iteration simply won't work for an HTMLCollection. for/in迭代对于HTMLCollection根本不起作用。


See http://jsfiddle.net/jfriend00/FzZ2H/ for why you can't iterate an HTMLCollection with for/in . 有关为什么无法使用for/in迭代HTMLCollection的信息,请参见http://jsfiddle.net/jfriend00/FzZ2H/ 。

In Firefox, your for/in iteration would return these items (all the iterable properties of the object): 在Firefox中, for/in迭代将返回以下项(对象的所有可迭代属性):

0
1
2
item
namedItem
@@iterator
length

Hopefully, now you can see why you want to use for (var i = 0; i < list.length; i++) instead so you just get 0 , 1 and 2 in your iteration. 我们希望,现在你可以看到为什么要使用for (var i = 0; i < list.length; i++)代替你只会得到012中的迭代。


Following below is an evolution of how browsers have evolved through the time period 2015-2018 giving you additional ways to iterate. 以下是浏览器在2015-2018年期间的演变方式的演变,为您提供了其他迭代方式。 None of these are now needed in modern browsers since you can use the options described above. 由于您可以使用上述选项,因此现代浏览器现在不需要这些。

Update for ES6 in 2015 2015年ES6更新

Added to ES6 is Array.from() that will convert an array-like structure to an actual array. ES6中添加了Array.from() ,它将把类似数组的结构转换为实际数组。 That allows one to enumerate a list directly like this: 这样就可以像这样直接枚举列表:

"use strict";Array.from(document.getElementsByClassName("events")).forEach(function(item) {console.log(item.id);
});

Working demo (in Firefox, Chrome, and Edge as of April 2016): https://jsfiddle.net/jfriend00/8ar4xn2s/ 工作演示(截至2016年4月在Firefox,Chrome和Edge中): https : //jsfiddle.net/jfriend00/8ar4xn2s/


Update for ES6 in 2016 2016年ES6更新

You can now use the ES6 for/of construct with a NodeList and an HTMLCollection by just adding this to your code: 现在,只需将ES6 for / of构造添加到代码中,即可将其与NodeListHTMLCollection使用:

NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
HTMLCollection.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];

Then, you can do: 然后,您可以执行以下操作:

var list = document.getElementsByClassName("events");
for (var item of list) {console.log(item.id);
}

This works in the current version of Chrome, Firefox, and Edge. 在当前版本的Chrome,Firefox和Edge中有效。 This works because it attaches the Array iterator to both the NodeList and HTMLCollection prototypes so that when for/of iterates them, it uses the Array iterator to iterate them. 之所以行之有效,是因为它将Array迭代器附加到NodeList和HTMLCollection原型上,以便当for / of对其进行迭代时,它使用Array迭代器对其进行迭代。

Working demo: http://jsfiddle.net/jfriend00/joy06u4e/ . 工作演示: http : //jsfiddle.net/jfriend00/joy06u4e/ 。


Second Update for ES6 in Dec 2016 ES6的第二次更新于2016年12月

As of Dec 2016, Symbol.iterator support has been built-in to Chrome v54 and Firefox v50 so the code below works by itself. 截至2016年12月,Chrome v54和Firefox v50内置了Symbol.iterator支持,因此以下代码可独立运行。 It is not yet built-in for Edge. Edge尚未内置。

var list = document.getElementsByClassName("events");
for (let item of list) {console.log(item.id);
}

Working demo (in Chrome and Firefox): http://jsfiddle.net/jfriend00/3ddpz8sp/ 工作演示(在Chrome和Firefox中): http : //jsfiddle.net/jfriend00/3ddpz8sp/

Third Update for ES6 in Dec 2017 ES6的第三次更新(2017年12月)

As of Dec. 2017, this capability works in Edge 41.16299.15.0 for a nodeList as in document.querySelectorAll() , but not an HTMLCollection as in document.getElementsByClassName() so you have to manually assign the iterator to use it in Edge for an HTMLCollection . 截至2017年12月,此功能在Edge 41.16299.15.0中可用于document.querySelectorAll()nodeList ,但不适用于document.getElementsByClassName()HTMLCollection ,因此您必须手动分配迭代器才能在Edge中使用一个HTMLCollection It is a total mystery why they'd fix one collection type, but not the other. 为什么要修复一种收集类型而不解决另一种收集类型,这完全是个谜。 But, you can at least use the result of document.querySelectorAll() with ES6 for/of syntax in current versions of Edge now. 但是,现在至少可以在当前版本的Edge中将带有ES6的document.querySelectorAll()结果for/of语法。

I've also updated the above jsFiddle so it tests both HTMLCollection and nodeList separately and captures the output in the jsFiddle itself. 我还更新了上面的jsFiddle,因此它分别测试了HTMLCollectionnodeList并捕获了jsFiddle本身的输出。

Fourth Update for ES6 in Mar 2018 ES6的第四次更新于2018年3月

Per mesqueeeb, Symbol.iterator support has been built-in to Safari too, so you can use for (let item of list) for either document.getElementsByClassName() or document.querySelectorAll() . 对于每个中队, Symbol.iterator支持也已内置到Safari中,因此您可以将document.getElementsByClassName()document.querySelectorAll() for (let item of list) document.querySelectorAll()

Fifth Update for ES6 in Apr 2018 ES6的第五次更新于2018年4月

Apparently, support for iterating an HTMLCollection with for/of will be coming to Edge 18 in Fall 2018. 显然,对for/of迭代HTMLCollection支持将在2018年秋季的Edge 18中提供。

Sixth Update for ES6 in Nov 2018 ES6的第六次更新于2018年11月

I can confirm that with Microsoft Edge v18 (that is included in the Fall 2018 Windows Update), you can now iterate both an HTMLCollection and a NodeList with for/of in Edge. 我可以确认使用Microsoft Edge v18(包含在2018年秋季的Windows Update中)现在可以在Edge中使用for / of迭代HTMLCollection和NodeList。

So, now all modern browsers contain native support for for/of iteration of both the HTMLCollection and NodeList objects. 因此,现在所有现代浏览器都原生支持HTMLCollection和NodeList对象的for/of迭代。


#4楼

You can't use for / in on NodeList s or HTMLCollection s. 您不能使用for / inNodeList秒或HTMLCollection秒。 However, you can use some Array.prototype methods, as long as you .call() them and pass in the NodeList or HTMLCollection as this . 但是,你可以使用一些Array.prototype方法,只要你.call()他们,并通过在NodeListHTMLCollection作为this

So consider the following as an alternative to jfriend00's for loop : 因此,请考虑以下内容作为jfriend00的for循环的替代方法:

var list= document.getElementsByClassName("events");
[].forEach.call(list, function(el) {console.log(el.id);
});

There's a good article on MDN that covers this technique. 在MDN上有一篇很好的文章介绍了该技术。 Note their warning about browser compatibility though: 请注意他们关于浏览器兼容性的警告:

[...] passing a host object (like a NodeList ) as this to a native method (such as forEach ) is not guaranteed to work in all browsers and is known to fail in some. 不能将主机对象(例如NodeListthis传递给本机方法(例如forEach ),不能保证在所有浏览器中都能正常工作,并且已知在某些浏览器中会失败。

So while this approach is convenient, a for loop may be the most browser-compatible solution. 因此,尽管这种方法很方便,但是for循环可能是与浏览器最兼容的解决方案。

Update (Aug 30, 2014): Eventually you'll be able to use ES6 for / of ! 更新(2014年8月30日):最终,您将可以for / of使用ES6 !

var list = document.getElementsByClassName("events");
for (el of list)console.log(el.id);

It's already supported in recent versions of Chrome and Firefox. Chrome和Firefox的最新版本已支持该功能。


#5楼

As of March 2016, in Chrome 49.0, for...of works for HTMLCollection : 截至2016年3月,在Chrome 49.0中, for...of用于HTMLCollection for...of

this.headers = this.getElementsByTagName("header");for (var header of this.headers) {console.log(header);
}

See here the documentation . 请参阅此处的文档 。

But it only works if you apply the following workaround before using the for...of : 但是,只有在使用for...of 之前应用以下变通方法时它才有效:

HTMLCollection.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];

The same is necessary for using for...of with NodeList : for...ofNodeList一起使用同样需要:

NamedNodeMap.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];

I believe/hope for...of will soon work without the above workaround. 我相信/希望for...of很快能在没有上述解决方法的情况下工作。 The open issue is here: 未解决的问题在这里:

https://bugs.chromium.org/p/chromium/issues/detail?id=401699 https://bugs.chromium.org/p/chromium/issues/detail?id=401699

Update: See Expenzor's comment below: This has been fixed as of April 2016. You don't need to add HTMLCollection.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator]; 更新:请参阅下面的Expenzor注释: 截至2016年4月,此问题已得到修复。您无需添加HTMLCollection.prototype [Symbol.iterator] = Array.prototype [Symbol.iterator]; to iterate over an HTMLCollection with for...of 遍历带有... of的HTMLCollection


#6楼

In ES6, you could do something like [...collection] , or Array.from(collection) , 在ES6中,您可以执行[...collection]Array.from(collection)

let someCollection = document.querySelectorAll(someSelector)
[...someCollection].forEach(someFn)
//or
Array.from(collection).forEach(someFn)

Eg:- 例如:-

    navDoms = document.getElementsByClassName('nav-container');Array.from(navDoms).forEach(function(navDom){//implement function operations});

HTMLCollection元素的For循环相关推荐

  1. java 删除list元素_JAVA中循环删除list中元素的方法总结

    印象中循环删除list中的元素使用for循环的方式是有问题的,但是可以使用增强的for循环,然后今天在使用时发现报错了,然后去科普了一下,再然后发现这是一个误区.下面就来讲一讲..伸手党可直接跳至文末 ...

  2. 【C语言练习】【指针】定义一个函数move,实现将长度为n、名为a的序列中,各元素依次顺序循环,右移m个位置

    题目 下列函数move的功能是:实现将长度为n.名为a的序列中,各元素依次顺序循环,右移m个位置. 例如:对于序列a=(1,3,5,7,9,11),若m=2,则循环右移后的结果为a=(9,11,1,3 ...

  3. java for循环删除元素_JAVA中循环删除list中元素的方法总结

    JAVA中循环遍历list有三种方式for循环.增强for循环(也就是常说的foreach循环).iterator遍历. 1.for循环遍历list for(int i=0;i if(list.get ...

  4. 问题:数组的循环左移。要求设计三种算法,将数组中的N个元素能够实现循环左移p个位置。

    问题重述:数组的循环左移.要求设计三种算法,将数组中的N个元素能够实现循环左移p个位置. 算法1: 先将数组中的前p个元素存放在一个临时数组中,再将余下的N-p个元素左移p个位置,最后将前p个元素从临 ...

  5. js获取class为xx的元素,并循环使用

    // 获取class为email-tag的元素: var elements = document.getElementsByClassName('email-tag'); // 循环获取到的元素集合 ...

  6. c语言将数组元素循环右移k位,把一个含有N个元素的数组循环右移K位

    普通解法: 可以每次将数组中的元素右移一位,循环K次.每个元素右移N位后都会回到自己的位置上.因此,如果K > N,右移K-N之后的数组序列跟右移K位的结果是一样的.进而可得出一条通用的规律:右 ...

  7. java set遍历删除元素_java中循环遍历删除List和Set集合中元素的方法

    今天在做项目时,需要删除List和Set中的某些元素,当时使用边遍历,边删除的方法,却报了以下异常: ConcurrentModificationException 为了以后不忘记,使用烂笔头把它记录 ...

  8. python list遍历定位元素_python for循环,第二遍定位不到元素?

    @ycyzharry: 也不行,我的代码 import unittest import time import xlrd from selenium import webdriver import s ...

  9. 在循环中正确找到对应DOM元素的索引

    有个网友问了个问题,如下的html,为什么点击所有的段落p输出都是5,而不是alert出对应的0,1,2,3,4. <!DOCTYPE HTML> <html> <hea ...

最新文章

  1. 离职后竟半夜偷溜回办公室写代码?一个为自由软件而战斗的程序员
  2. C# 8新提案让泛型Attribute成为现实
  3. ASP.NET中级学习2
  4. 2021-04-29 Python绘制柱状图之可视化神器Pyecharts
  5. PAT条条大路通罗马
  6. hdu4099(斐波那契数+字典树)
  7. spring怎么设置定时任务为每天凌晨2点执行和每小时执行一次?(亲测)
  8. Java 中的双重检查(Double-Check)
  9. WCF技术剖析之十七:消息(Message)详解(下篇)
  10. 命名空间:不只是代码封装
  11. IDEA快捷键拆解系列(七):Analyze篇
  12. 二、自定义控件之RadioButtonList
  13. Wilcoxon Signed-Rank Test
  14. 分享一下我在东方时尚学车的经历
  15. 内大计算机学院在哪个校区,2021年福建船政交通职业学院有几个校区,大一新生在哪个校区...
  16. 双目立体匹配修炼之路
  17. css常用样式(文字样式、边框样式、背景样式)
  18. 关于Linux系统中文件名中带有空格问题分析
  19. 在网页上打印时用javascript设置打印区域和不打印区域,分页等
  20. 7-5 盲盒包装流水线

热门文章

  1. 在Struts 2.0中国际化(i18n)您的应用程序
  2. Android 使用android-support-multidex解决Dex超出方法数的限制问题,让你的应用不再爆棚
  3. COM中的IDL语言的难点之接口指针
  4. 算法---------至少有K个重复字符的最长子串(Java版本)
  5. 第十、十一周项目三-警察和厨师(2)
  6. 第五周项目一-三角形类雏形(3)
  7. Android开源控件ViewPager Indicator的使用方法
  8. mysql客户端连接hive_连接Hive的客户端界面工具–SQuirrel SQL Client
  9. JavaScript语言基础13
  10. 用Spark实现简单的单词统计