In risposta alla domanda originale, si sta utilizzando in for/inmodo errato. Nel tuo codice, keyè l'indice. Quindi, per ottenere il valore dallo pseudo-array, dovresti fare list[key]e ottenere l'id, lo faresti list[key].id. Ma non dovresti farlo for/inin primo luogo.
Riepilogo (aggiunto a dicembre 2018)
Non usare mai for/inper iterare un nodeList o un HTMLCollection. I motivi per evitarlo sono descritti di seguito.
Tutte le versioni recenti dei browser moderni (Safari, Firefox, Chrome, Edge) supportano tutte l' for/ofiterazione su elenchi DOM come nodeListo HTMLCollection.
Ecco un esempio:
var list = document.getElementsByClassName("events");
for (let item of list) {
console.log(item.id);
}
Per includere browser meno recenti (inclusi elementi come IE), funzionerà ovunque:
var list= document.getElementsByClassName("events");
for (var i = 0; i < list.length; i++) {
console.log(list[i].id); //second console output
}
Spiegazione del perché non si dovrebbe usare for/in
for/inè pensato per iterare le proprietà di un oggetto. Ciò significa che restituirà tutte le proprietà iterabili di un oggetto. Mentre può sembrare funzionare per un array (restituendo elementi array o pseudo-array), può anche restituire altre proprietà dell'oggetto che non sono quelle che ti aspetti dagli elementi simili a array. E, indovina, un oggetto HTMLCollectiono nodeListpossono entrambi avere altre proprietà che verranno restituite con for/inun'iterazione. Ho appena provato questo in Chrome e iterandolo nel modo in cui lo stavi iterando recupererà gli elementi nell'elenco (indici 0, 1, 2, ecc ...), ma recupererà anche le proprietà lengthe item. L' for/initerazione semplicemente non funzionerà per un HTMLCollection.
Vedi http://jsfiddle.net/jfriend00/FzZ2H/ per i motivi per cui non puoi ripetere una raccolta HTMLC for/in.
In Firefox, la tua for/initerazione restituirebbe questi elementi (tutte le proprietà iterabili dell'oggetto):
0
1
2
item
namedItem
@@iterator
length
Si spera, ora si può vedere perché si desidera utilizzare for (var i = 0; i < list.length; i++)invece così basta avere 0, 1e 2nella vostra iterazione.
Di seguito è riportata un'evoluzione del modo in cui i browser si sono evoluti nel periodo 2015-2018 offrendo ulteriori modi per iterare. Nessuno di questi è ora necessario nei browser moderni poiché è possibile utilizzare le opzioni sopra descritte.
Aggiornamento per ES6 nel 2015
Aggiunto a ES6 è Array.from()che convertirà una struttura simile ad un array in un array reale. Ciò consente di enumerare un elenco direttamente come questo:
"use strict";
Array.from(document.getElementsByClassName("events")).forEach(function(item) {
console.log(item.id);
});
Demo funzionante (in Firefox, Chrome e Edge a partire da aprile 2016): https://jsfiddle.net/jfriend00/8ar4xn2s/
Aggiornamento per ES6 nel 2016
Ora puoi usare ES6 per / of construct con a NodeListe an HTMLCollectionsemplicemente aggiungendo questo al tuo codice:
NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
HTMLCollection.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
Quindi, puoi fare:
var list = document.getElementsByClassName("events");
for (var item of list) {
console.log(item.id);
}
Funziona con la versione corrente di Chrome, Firefox e Edge. Questo funziona perché collega l'iteratore di array a entrambi i prototipi NodeList e HTMLCollection in modo che, quando per / di iterali, utilizza l'iteratore di array per iterarli.
Demo funzionante: http://jsfiddle.net/jfriend00/joy06u4e/ .
Secondo aggiornamento per ES6 nel dicembre 2016
A partire da dicembre 2016, il Symbol.iteratorsupporto è stato integrato in Chrome v54 e Firefox v50, quindi il codice seguente funziona da solo. Non è ancora integrato per Edge.
var list = document.getElementsByClassName("events");
for (let item of list) {
console.log(item.id);
}
Demo funzionante (in Chrome e Firefox): http://jsfiddle.net/jfriend00/3ddpz8sp/
Terzo aggiornamento per ES6 nel dicembre 2017
A partire da dicembre 2017, questa funzionalità funziona in Edge 41.16299.15.0 per un nodeListcome in document.querySelectorAll(), ma non HTMLCollectioncome in, document.getElementsByClassName()quindi è necessario assegnare manualmente l'iteratore per usarlo in Edge per un HTMLCollection. È un mistero totale il motivo per cui avrebbero corretto un tipo di raccolta, ma non l'altro. Ma ora puoi almeno usare il risultato di document.querySelectorAll()con la for/ofsintassi ES6 nelle versioni attuali di Edge.
Ho anche aggiornato il sopra jsFiddle in modo che controlla sia HTMLCollectione nodeListseparatamente e cattura l'uscita nel jsFiddle stesso.
Quarto aggiornamento per ES6 a marzo 2018
Per mesqueeeb, il Symbol.iteratorsupporto è stato integrato anche in Safari, quindi puoi usarlo for (let item of list)per document.getElementsByClassName()o document.querySelectorAll().
Quinto aggiornamento per ES6 nell'aprile 2018
Apparentemente, il supporto per iterare un HTMLCollectioncon for/ofarriverà a Edge 18 nell'autunno 2018.
Sesto aggiornamento per ES6 nel novembre 2018
Posso confermare che con Microsoft Edge v18 (incluso in Windows Update dell'autunno 2018), è ora possibile iterare sia un HTMLCollection che un NodeList con for / of in Edge.
Quindi, ora tutti i browser moderni contengono supporto nativo per l' for/ofiterazione degli oggetti HTMLCollection e NodeList.