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 undefinedla 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/inincorrectamente. En su código,keyes 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/inen primer lugar.Resumen (agregado en diciembre de 2018)
No lo use nunca
for/inpara 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/ofiteración en listas DOM comonodeListoHTMLCollection.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/infor/inestá 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é, unaHTMLCollectiononodeListobjeto puede tener tanto otras propiedades que serán devueltos con unafor/initeració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 propiedadeslengthyitem. Lafor/initeració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/initeració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,1y2en 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
NodeListy anHTMLCollectionsimplemente 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.iteratorsoporte 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
nodeListas indocument.querySelectorAll(), pero no unHTMLCollectionas 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/ofen las versiones actuales de Edge ahora.También actualicé el jsFiddle anterior para que pruebe ambos
HTMLCollectiony pornodeListseparado y capture la salida en el propio jsFiddle.Cuarta actualización para ES6 en marzo de 2018
Según mesqueeeb, el
Symbol.iteratorsoporte 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
HTMLCollectionconfor/ofllegará 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/ofiteración de los objetos HTMLCollection y NodeList.fuente
No puedes usar
for/inonNodeLists oHTMLCollections. Sin embargo, puede usar algunosArray.prototypemétodos, siempre que.call()los use y pase elNodeListoHTMLCollectioncomothis.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
forbucle 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 ... offunciona.En ES6, podrías hacer algo como
[...collection], oArray.from(collection),P.ej:-
fuente
[...row.cells].forEachlugar 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
NodeListya 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.fromes usarArray.prototype.forEach.callpara 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
forbucle si estás en IE9 o superior.En ES5, hay dos buenas opciones. En primer lugar, se puede "tomar prestado"
Array'sforEachcomo Evan menciona .Pero aún mejor ...
Uso
Object.keys(), que no tieneforEachy filtros para "propias propiedades" automáticamente.Es decir,
Object.keyses esencialmente equivalente a hacer unfor... incon aHasOwnProperty, pero es mucho más suave.fuente
A partir de marzo de 2016, en Chrome 49.0,
for...offunciona 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...ofconNodeList:Creo / espero
for...ofque 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 unHTMLCollectionconfor...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 losHTMLCollectionque no están destinados a ser elementos de la colección.