Estoy tratando de establecer get id de todos los elementos en un HTMLCollectionOf
. Escribí el siguiente código:
var list = document.getElementsByClassName("events");
console.log(list[0].id);
for (key in list) {
console.log(key.id);
}
Pero obtuve el siguiente resultado en la consola:
event1
undefined
que no es lo que esperaba ¿Por qué la salida de la segunda consola es la primera salida de undefined
la consola event1
?
javascript
dom
Neurona
fuente
fuente
Array.from(document.getElementsByClassName("events")).forEach(function(item) {
Respuestas:
En respuesta a la pregunta original, está utilizando
for/in
incorrectamente. En su código,key
es el índice. Entonces, para obtener el valor de la pseudo-matriz, tendría que hacerlist[key]
y para obtener la identificación, lo haríalist[key].id
. Pero, no deberías estar haciendo estofor/in
en primer lugar.Resumen (agregado en diciembre de 2018)
No lo use nunca
for/in
para iterar una lista de nodos o una colección HTMLC. Las razones para evitarlo se describen a continuación.Todas las versiones recientes de los navegadores modernos (Safari, Firefox, Chrome, Edge) admiten la
for/of
iteración en listas DOM comonodeList
oHTMLCollection
.Aquí hay un ejemplo:
Para incluir navegadores antiguos (incluidos elementos como IE), esto funcionará en todas partes:
Explicación de por qué no debe usar
for/in
for/in
está destinado a iterar las propiedades de un objeto. Eso significa que devolverá todas las propiedades iterables de un objeto. Si bien puede parecer que funciona para una matriz (elementos de matriz devueltos o elementos de pseudo-matriz), también puede devolver otras propiedades del objeto que no son lo que espera de los elementos tipo matriz. Y, adivina qué, unaHTMLCollection
onodeList
objeto puede tener tanto otras propiedades que serán devueltos con unafor/in
iteración. Acabo de probar esto en Chrome e iterarlo de la forma en que lo hiciste recuperará los elementos de la lista (índices 0, 1, 2, etc.), pero también recuperará las propiedadeslength
yitem
. Lafor/in
iteración simplemente no funcionará para una colección HTMLC.Consulte http://jsfiddle.net/jfriend00/FzZ2H/ para ver por qué no puede iterar una colección HTMLC con
for/in
.En Firefox, su
for/in
iteración devolvería estos elementos (todas las propiedades iterables del objeto):Con suerte, ahora puedes ver por qué quieres usar
for (var i = 0; i < list.length; i++)
en su lugar, así que solo obtienes0
,1
y2
en tu iteración.A continuación se muestra una evolución de cómo los navegadores han evolucionado durante el período 2015-2018, ofreciéndole formas adicionales de iterar. Ninguno de estos ahora es necesario en los navegadores modernos, ya que puede usar las opciones descritas anteriormente.
Actualización para ES6 en 2015
Se agregó a ES6
Array.from()
que convertirá una estructura tipo matriz en una matriz real. Eso le permite a uno enumerar una lista directamente así:Demostración de trabajo (en Firefox, Chrome y Edge a partir de abril de 2016): https://jsfiddle.net/jfriend00/8ar4xn2s/
Actualización para ES6 en 2016
Ahora puede usar el ES6 para / of construct con a
NodeList
y anHTMLCollection
simplemente agregando esto a su código:Entonces, puedes hacer:
Esto funciona en la versión actual de Chrome, Firefox y Edge. Esto funciona porque une el iterador de matriz a los prototipos de NodeList y HTMLCollection para que cuando for / of los itere, use el iterador de matriz para iterarlos.
Demostración de trabajo: http://jsfiddle.net/jfriend00/joy06u4e/ .
Segunda actualización para ES6 en diciembre de 2016
A partir de diciembre de 2016, el
Symbol.iterator
soporte se ha incorporado a Chrome v54 y Firefox v50, por lo que el siguiente código funciona por sí solo. Todavía no está integrado para Edge.Demostración de trabajo (en Chrome y Firefox): http://jsfiddle.net/jfriend00/3ddpz8sp/
Tercera actualización para ES6 en diciembre de 2017
A partir de diciembre de 2017, esta capacidad funciona en Edge 41.16299.15.0 para un
nodeList
as indocument.querySelectorAll()
, pero no unHTMLCollection
as in,document.getElementsByClassName()
por lo que debe asignar manualmente el iterador para usarlo en Edge para unHTMLCollection
. Es un misterio total por qué arreglarían un tipo de colección, pero no el otro. Pero, al menos puede usar el resultado de la sintaxisdocument.querySelectorAll()
ES6for/of
en las versiones actuales de Edge ahora.También actualicé el jsFiddle anterior para que pruebe ambos
HTMLCollection
y pornodeList
separado y capture la salida en el propio jsFiddle.Cuarta actualización para ES6 en marzo de 2018
Según mesqueeeb, el
Symbol.iterator
soporte también se ha incorporado a Safari, por lo que puede usarlofor (let item of list)
paradocument.getElementsByClassName()
odocument.querySelectorAll()
.Quinta actualización para ES6 en abril de 2018
Aparentemente, el soporte para iterar un
HTMLCollection
confor/of
llegará a Edge 18 en el otoño de 2018.Sexta actualización para ES6 en noviembre de 2018
Puedo confirmar que con Microsoft Edge v18 (que se incluye en la actualización de Windows de otoño de 2018), ahora puede iterar tanto una colección HTMLC como una NodeList con for / of en Edge.
Por lo tanto, ahora todos los navegadores modernos contienen soporte nativo para la
for/of
iteración de los objetos HTMLCollection y NodeList.fuente
No puedes usar
for
/in
onNodeList
s oHTMLCollection
s. Sin embargo, puede usar algunosArray.prototype
métodos, siempre que.call()
los use y pase elNodeList
oHTMLCollection
comothis
.Considere lo siguiente como una alternativa al bucle de jfriend00
for
:Hay un buen artículo sobre MDN que cubre esta técnica. Sin embargo, tenga en cuenta su advertencia sobre la compatibilidad del navegador:
Entonces, si bien este enfoque es conveniente, un
for
bucle puede ser la solución más compatible con el navegador.Actualización (30 de agosto de 2014): ¡ Eventualmente podrás usar ES6
for
/of
!Ya es compatible con versiones recientes de Chrome y Firefox.
fuente
<select multiple>
. Ejemplo:[].map.call(multiSelect.selectedOptions, function(option) { return option.value; })
for ... of
funciona.En ES6, podrías hacer algo como
[...collection]
, oArray.from(collection)
,P.ej:-
fuente
[...row.cells].forEach
lugar de hacer unrow.querySelectorAll('td')
puedes agregar estas dos líneas:
HTMLCollection es devuelta por getElementsByClassName y getElementsByTagName
NodeList es devuelto por querySelectorAll
De esta manera puedes hacer un forEach:
fuente
NodeList
ya tieneforEach()
.Tuve un problema al usar forEach en IE 11 y también Firefox 49
He encontrado una solución como esta
fuente
Alternativa a
Array.from
es usarArray.prototype.forEach.call
para cada:
Array.prototype.forEach.call(htmlCollection, i => { console.log(i) });
mapa:
Array.prototype.map.call(htmlCollection, i => { console.log(i) });
ect ...
fuente
No hay ninguna razón para usar las funciones de es6 para escapar del
for
bucle si estás en IE9 o superior.En ES5, hay dos buenas opciones. En primer lugar, se puede "tomar prestado"
Array
'sforEach
como Evan menciona .Pero aún mejor ...
Uso
Object.keys()
, que no tieneforEach
y filtros para "propias propiedades" automáticamente.Es decir,
Object.keys
es esencialmente equivalente a hacer unfor... in
con aHasOwnProperty
, pero es mucho más suave.fuente
A partir de marzo de 2016, en Chrome 49.0,
for...of
funciona paraHTMLCollection
:Vea aquí la documentación .
Pero solo funciona si aplica la siguiente solución antes de usar
for...of
:Lo mismo es necesario para usar
for...of
conNodeList
:Creo / espero
for...of
que pronto funcione sin la solución anterior. El tema abierto está aquí:Actualización: vea el comentario de Expenzor a continuación: Esto se ha solucionado a partir de abril de 2016. No necesita agregar HTMLCollection.prototype [Symbol.iterator] = Array.prototype [Symbol.iterator]; iterar sobre una colección HTMLC con para ... de
fuente
HTMLCollection.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
para iterar sobre unHTMLCollection
confor...of
.Nervioso
fuente
Solución fácil que siempre uso
Después de esto, puede ejecutar cualquier método de matriz deseado en la selección
fuente
si usa versiones anteriores de ES, (ES5 por ejemplo), puede usar
as any
:fuente
Quieres cambiarlo a
fuente
for (key in list)
devolverá varias propiedades de losHTMLCollection
que no están destinados a ser elementos de la colección.