Em resposta à pergunta original, você está usando for/in
incorretamente. No seu código, key
é o índice. Portanto, para obter o valor da pseudo-matriz, você teria que fazer list[key]
e obter o ID, você faria list[key].id
. Mas você não deve fazer isso for/in
em primeiro lugar.
Resumo (adicionado em dezembro de 2018)
Nunca use for/in
para iterar um nodeList ou um HTMLCollection. Os motivos para evitá-lo estão descritos abaixo.
Todas as versões recentes de navegadores modernos (Safari, Firefox, Chrome, Edge) todo o apoio for/of
iteração no DOM lista tais nodeList
ou HTMLCollection
.
Aqui está um exemplo:
var list = document.getElementsByClassName("events");
for (let item of list) {
console.log(item.id);
}
Para incluir navegadores mais antigos (incluindo coisas como o IE), isso funcionará em qualquer lugar:
var list= document.getElementsByClassName("events");
for (var i = 0; i < list.length; i++) {
console.log(list[i].id); //second console output
}
Explicação sobre por que você não deve usar for/in
for/in
destina-se a iterar as propriedades de um objeto. Isso significa que ele retornará todas as propriedades iteráveis de um objeto. Embora pareça funcionar para uma matriz (retornando elementos da matriz ou elementos de pseudo-matriz), também pode retornar outras propriedades do objeto que não são o que você espera dos elementos semelhantes à matriz. E, adivinhe, um objeto HTMLCollection
ou nodeList
pode ter outras propriedades que serão retornadas com uma for/in
iteração. Eu apenas tentei isso no Chrome e a iteração da maneira que você estava iterando recuperará os itens da lista (índices 0, 1, 2, etc ...), mas também recuperará as propriedades length
e item
. A for/in
iteração simplesmente não funcionará para uma HTMLCollection.
Veja http://jsfiddle.net/jfriend00/FzZ2H/ para saber por que você não pode iterar uma HTMLCollection for/in
.
No Firefox, sua for/in
iteração retornaria esses itens (todas as propriedades iteráveis do objeto):
0
1
2
item
namedItem
@@iterator
length
Felizmente, agora você pode ver por que você deseja usar for (var i = 0; i < list.length; i++)
em vez de modo que você acabou de começar 0
, 1
e 2
em sua iteração.
A seguir, é apresentada uma evolução de como os navegadores evoluíram ao longo do período 2015-2018, oferecendo maneiras adicionais de iterar. Agora nada disso é necessário em navegadores modernos, pois você pode usar as opções descritas acima.
Atualização para ES6 em 2015
Adicionado ao ES6 é Array.from()
que ele converterá uma estrutura semelhante a uma matriz em uma matriz real. Isso permite enumerar uma lista diretamente assim:
"use strict";
Array.from(document.getElementsByClassName("events")).forEach(function(item) {
console.log(item.id);
});
Demonstração de trabalho (no Firefox, Chrome e Edge em abril de 2016): https://jsfiddle.net/jfriend00/8ar4xn2s/
Atualização para ES6 em 2016
Agora você pode usar o ES6 para / de construção com um NodeList
e um HTMLCollection
por apenas adicionando isso ao seu código:
NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
HTMLCollection.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
Então, você pode fazer:
var list = document.getElementsByClassName("events");
for (var item of list) {
console.log(item.id);
}
Isso funciona na versão atual do Chrome, Firefox e Edge. Isso funciona porque anexa o iterador Array aos protótipos NodeList e HTMLCollection, para que, quando for iterado por / deles, use o iterador Array para iterá-los.
Demonstração de trabalho: http://jsfiddle.net/jfriend00/joy06u4e/ .
Segunda atualização do ES6 em dezembro de 2016
Desde dezembro de 2016, o Symbol.iterator
suporte foi incorporado ao Chrome v54 e Firefox v50, portanto, o código abaixo funciona por si só. Ainda não está embutido no Edge.
var list = document.getElementsByClassName("events");
for (let item of list) {
console.log(item.id);
}
Demonstração de trabalho (no Chrome e Firefox): http://jsfiddle.net/jfriend00/3ddpz8sp/
Terceira atualização para ES6 em dezembro de 2017
A partir de dezembro de 2017, esse recurso funcionaria no Edge 41.16299.15.0 para a nodeList
como em document.querySelectorAll()
, mas não para HTMLCollection
como, document.getElementsByClassName()
portanto, você deve atribuir manualmente o iterador para usá-lo no Edge para um HTMLCollection
. É um mistério total o motivo pelo qual eles consertam um tipo de coleção, mas não o outro. Porém, você pode pelo menos usar o resultado da sintaxe document.querySelectorAll()
ES6 for/of
nas versões atuais do Edge agora.
Também atualizei o jsFiddle acima para que ele teste ambos HTMLCollection
e nodeList
separadamente e capture a saída no próprio jsFiddle.
Quarta atualização do ES6 em março de 2018
Por mesqueeeb, o Symbol.iterator
suporte também foi incorporado ao Safari, para que você possa usar for (let item of list)
um document.getElementsByClassName()
ou outro document.querySelectorAll()
.
Quinta atualização para ES6 em abril de 2018
Aparentemente, o suporte para iterar um HTMLCollection
com for/of
chegará ao Edge 18 no outono de 2018.
Sexta atualização para ES6 em novembro de 2018
Posso confirmar que, com o Microsoft Edge v18 (incluído no Windows Update de outono de 2018), agora você pode iterar um HTMLCollection e um NodeList com for / of no Edge.
Portanto, agora todos os navegadores modernos contêm suporte nativo para for/of
iteração dos objetos HTMLCollection e NodeList.