J'essaie de définir get id de tous les éléments dans un HTMLCollectionOf
. J'ai écrit le code suivant:
var list = document.getElementsByClassName("events");
console.log(list[0].id);
for (key in list) {
console.log(key.id);
}
Mais j'ai obtenu la sortie suivante dans la console:
event1
undefined
ce qui n'est pas ce que j'attendais. Pourquoi la deuxième sortie de la console est- undefined
elle la première sortie de la console event1
?
javascript
dom
Neurone
la source
la source
Array.from(document.getElementsByClassName("events")).forEach(function(item) {
Réponses:
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 fairelist[key]
et pour obtenir l'id, vous le feriezlist[key].id
. Mais, vous ne devriez pas faire celafor/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 telnodeList
ouHTMLCollection
.Voici un exemple:
Pour inclure des navigateurs plus anciens (y compris des choses comme IE), cela fonctionnera partout:
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, unHTMLCollection
ou unnodeList
objet peut tous deux avoir d'autres propriétés qui seront retournées avec unefor/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éslength
etitem
. 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):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 juste0
,1
et2
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: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 anHTMLCollection
en ajoutant simplement ceci à votre code:Ensuite, vous pouvez faire:
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.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 indocument.querySelectorAll()
, mais pas unHTMLCollection
as indocument.getElementsByClassName()
, vous devez donc affecter manuellement l'itérateur pour l'utiliser dans Edge for anHTMLCollection
. 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 syntaxedocument.querySelectorAll()
ES6for/of
dans les versions actuelles d'Edge maintenant.J'ai également mis à jour le jsFiddle ci-dessus afin qu'il teste à la fois
HTMLCollection
etnodeList
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 utiliserfor (let item of list)
pourdocument.getElementsByClassName()
oudocument.querySelectorAll()
.Cinquième mise à jour pour ES6 en avril 2018
Apparemment, le support pour l'itération d'un
HTMLCollection
avecfor/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.la source
Vous ne pouvez pas utiliser
for
/in
surNodeList
s ouHTMLCollection
s. Cependant, vous pouvez utiliser certainesArray.prototype
méthodes, tant que vous.call()
les utilisez et passez leNodeList
ouHTMLCollection
commethis
.Considérez donc ce qui suit comme une alternative à la
for
boucle de jfriend00 :Il y a un bon article sur MDN qui couvre cette technique. Notez cependant leur avertissement concernant la compatibilité du navigateur:
Ainsi, bien que cette approche soit pratique, une
for
boucle peut être la solution la plus compatible avec les navigateurs.Mise à jour (30 août 2014): Finalement, vous pourrez utiliser ES6
for
/of
!Il est déjà pris en charge dans les versions récentes de Chrome et Firefox.
la source
<select multiple>
. Exemple:[].map.call(multiSelect.selectedOptions, function(option) { return option.value; })
for ... of
fonctionne.Dans ES6, vous pouvez faire quelque chose comme
[...collection]
, ouArray.from(collection)
,Par exemple:-
la source
[...row.cells].forEach
au lieu de faire unrow.querySelectorAll('td')
vous pouvez ajouter ces deux lignes:
HTMLCollection est renvoyé par getElementsByClassName et getElementsByTagName
NodeList est renvoyé par querySelectorAll
Comme ça, vous pouvez faire un forEach:
la source
NodeList
déjà le casforEach()
.J'ai eu un problème avec forEach dans IE 11 et aussi Firefox 49
J'ai trouvé une solution de contournement comme celle-ci
la source
Alternative à
Array.from
est d'utiliserArray.prototype.forEach.call
pour chaque:
Array.prototype.forEach.call(htmlCollection, i => { console.log(i) });
carte:
Array.prototype.map.call(htmlCollection, i => { console.log(i) });
ect ...
la source
Il n'y a aucune raison d'utiliser les fonctionnalités es6 pour échapper au
for
bouclage si vous êtes sur IE9 ou supérieur.Dans ES5, il existe deux bonnes options. D' abord, vous pouvez « »
Array
« sforEach
comme evan mentionne .Mais encore mieux ...
L' utilisation
Object.keys()
, qui ne disposeforEach
et les filtres à « propres propriétés » automatiquement.Autrement dit,
Object.keys
est essentiellement équivalent à faire unfor... in
avec unHasOwnProperty
, mais est beaucoup plus fluide.la source
Depuis mars 2016, dans Chrome 49.0,
for...of
fonctionne pourHTMLCollection
:Voir ici la documentation .
Mais cela ne fonctionne que si vous appliquez la solution de contournement suivante avant d' utiliser
for...of
:La même chose est nécessaire pour utiliser
for...of
avecNodeList
:Je crois / espère
for...of
fonctionnera bientôt sans la solution de contournement ci-dessus. Le problème ouvert est ici:Mise à jour: Voir le commentaire d'Expenzor ci-dessous: Cela a été corrigé en avril 2016. Vous n'avez pas besoin d'ajouter HTMLCollection.prototype [Symbol.iterator] = Array.prototype [Symbol.iterator]; pour itérer sur une HTMLCollection avec pour ... de
la source
HTMLCollection.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
d'itération sur unHTMLCollection
avecfor...of
.On Edge
la source
Solution de contournement facile que j'utilise toujours
Après cela, vous pouvez exécuter toutes les méthodes de tableau souhaitées sur la sélection
la source
si vous utilisez des versions plus anciennes d'ES (ES5 par exemple), vous pouvez utiliser
as any
:la source
Vous voulez le changer en
la source
for (key in list)
renverra plusieurs propriétés duHTMLCollection
qui ne sont pas censées être des éléments de la collection.