En réponse à la question d'origine, vous utilisez for/in
incorrectement. Dans votre code, key
est l'index. Donc, pour obtenir la valeur du pseudo-tableau, vous devez le faire list[key]
et pour obtenir l'id, vous le feriez list[key].id
. Mais, vous ne devriez pas faire cela for/in
en premier lieu.
Résumé (ajouté en décembre 2018)
Ne jamais utiliser for/in
pour itérer une nodeList ou une HTMLCollection. Les raisons de l'éviter sont décrites ci-dessous.
Toutes les versions récentes des navigateurs modernes (Safari, Firefox, Chrome Edge) tout l' appui for/of
itération sur liste DOM tel nodeList
ou HTMLCollection
.
Voici un exemple:
var list = document.getElementsByClassName("events");
for (let item of list) {
console.log(item.id);
}
Pour inclure des navigateurs plus anciens (y compris des choses comme IE), cela fonctionnera partout:
var list= document.getElementsByClassName("events");
for (var i = 0; i < list.length; i++) {
console.log(list[i].id); //second console output
}
Explication des raisons pour lesquelles vous ne devriez pas utiliser for/in
for/in
est destiné à itérer les propriétés d'un objet. Cela signifie qu'il renverra toutes les propriétés itérables d'un objet. Bien qu'il puisse sembler fonctionner pour un tableau (renvoyant des éléments de tableau ou des éléments de pseudo-tableau), il peut également renvoyer d'autres propriétés de l'objet qui ne correspondent pas à ce que vous attendez des éléments de type tableau. Et, devinez quoi, un HTMLCollection
ou un nodeList
objet peut tous deux avoir d'autres propriétés qui seront retournées avec une for/in
itération. Je viens de l'essayer dans Chrome et de l'itérer comme vous l'avez fait, il récupérera les éléments de la liste (index 0, 1, 2, etc ...), mais récupérera également les propriétés length
et item
. L' for/in
itération ne fonctionnera tout simplement pas pour une HTMLCollection.
Voir http://jsfiddle.net/jfriend00/FzZ2H/ pour savoir pourquoi vous ne pouvez pas itérer une HTMLCollection avec for/in
.
Dans Firefox, votre for/in
itération retournerait ces éléments (toutes les propriétés itérables de l'objet):
0
1
2
item
namedItem
@@iterator
length
Avec un peu de chance, vous pouvez maintenant voir pourquoi vous souhaitez utiliser à la for (var i = 0; i < list.length; i++)
place, donc vous obtenez juste 0
, 1
et 2
dans votre itération.
Vous trouverez ci-dessous une évolution de la façon dont les navigateurs ont évolué au cours de la période 2015-2018, vous offrant des moyens supplémentaires d'itérer. Aucun de ces éléments n'est désormais nécessaire dans les navigateurs modernes, car vous pouvez utiliser les options décrites ci-dessus.
Mise à jour pour ES6 en 2015
Ajouté à ES6 Array.from()
, il convertira une structure de type tableau en un tableau réel. Cela permet d'énumérer une liste directement comme ceci:
"use strict";
Array.from(document.getElementsByClassName("events")).forEach(function(item) {
console.log(item.id);
});
Démo fonctionnelle (dans Firefox, Chrome et Edge à partir d'avril 2016): https://jsfiddle.net/jfriend00/8ar4xn2s/
Mise à jour pour ES6 en 2016
Vous pouvez maintenant utiliser la construction ES6 for / of avec a NodeList
et an HTMLCollection
en ajoutant simplement ceci à votre code:
NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
HTMLCollection.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
Ensuite, vous pouvez faire:
var list = document.getElementsByClassName("events");
for (var item of list) {
console.log(item.id);
}
Cela fonctionne dans la version actuelle de Chrome, Firefox et Edge. Cela fonctionne car il attache l'itérateur Array aux prototypes NodeList et HTMLCollection de sorte que lorsque pour / de les itère, il utilise l'itérateur Array pour les itérer.
Démo de travail: http://jsfiddle.net/jfriend00/joy06u4e/ .
Deuxième mise à jour pour ES6 en décembre 2016
Depuis décembre 2016, la Symbol.iterator
prise en charge a été intégrée à Chrome v54 et Firefox v50 afin que le code ci-dessous fonctionne seul. Il n'est pas encore intégré pour Edge.
var list = document.getElementsByClassName("events");
for (let item of list) {
console.log(item.id);
}
Démo de travail (dans Chrome et Firefox): http://jsfiddle.net/jfriend00/3ddpz8sp/
Troisième mise à jour pour ES6 en décembre 2017
Depuis décembre 2017, cette fonctionnalité fonctionne dans Edge 41.16299.15.0 pour un nodeList
as in document.querySelectorAll()
, mais pas un HTMLCollection
as in document.getElementsByClassName()
, vous devez donc affecter manuellement l'itérateur pour l'utiliser dans Edge for an HTMLCollection
. C'est un mystère total pourquoi ils ont fixé un type de collection, mais pas l'autre. Mais, vous pouvez au moins utiliser le résultat de la syntaxe document.querySelectorAll()
ES6 for/of
dans les versions actuelles d'Edge maintenant.
J'ai également mis à jour le jsFiddle ci-dessus afin qu'il teste à la fois HTMLCollection
et nodeList
séparément et capture la sortie dans le jsFiddle lui-même.
Quatrième mise à jour pour ES6 en mars 2018
Par mesqueeeb, la Symbol.iterator
prise en charge a également été intégrée à Safari, vous pouvez donc utiliser for (let item of list)
pour document.getElementsByClassName()
ou document.querySelectorAll()
.
Cinquième mise à jour pour ES6 en avril 2018
Apparemment, le support pour l'itération d'un HTMLCollection
avec for/of
arrivera à Edge 18 à l'automne 2018.
Sixième mise à jour pour ES6 en novembre 2018
Je peux confirmer qu'avec Microsoft Edge v18 (inclus dans la mise à jour Windows de l'automne 2018), vous pouvez désormais itérer à la fois une HTMLCollection et une NodeList avec for / of dans Edge.
Ainsi, tous les navigateurs modernes contiennent désormais une prise en charge native pour l' for/of
itération des objets HTMLCollection et NodeList.