JavaScript: boucle à travers tous les éléments retournés de getElementsByTagName

j'essaie de boucler tous les éléments retranchés de getElementsByTagName("input") en utilisant forEach. Une idée de pourquoi cela ne fonctionne pas en FF, Chrome ou IE?

<html>
    <head>
    </head>
    <body>
        <input type="text" value="" />
        <input type="text" value="" />
        <script>
            function ShowResults(value, index, ar) {
                alert(index);
            }
            var input = document.getElementsByTagName("input");
            alert(input.length);
            input.forEach(ShowResults);
    </script>
    </body>
</html>
32
demandé sur slayernoah 2013-10-11 22:15:41

8 réponses

vous devez convertir le nodelist en tableau avec ceci:

<html>
    <head>
    </head>
    <body>
        <input type="text" value="" />
        <input type="text" value="" />
        <script>
            function ShowResults(value, index, ar) {
                alert(index);
            }
            var input = document.getElementsByTagName("input");
            var inputList = Array.prototype.slice.call(input);
            alert(inputList.length);
            inputList.forEach(ShowResults);
    </script>
    </body>
</html>

ou utiliser pour boucle.

for(i = 0;i < input.length; i++)
{
    ShowResults(input[i].value);
}

et changer la fonction ShowResults en:

function ShowResults(value) {
   alert(value);
}
58
répondu Dvir 2013-10-11 18:24:55

Yay, ES6:

const children = [...parent.getElementsByTagName('tag')];
children.forEach((child) => { /* Do something; */ });

MDN Doc pour la Propagation de l'Opérateur ( ... )

28
répondu jtheletter 2016-12-17 04:59:58

parce que input n'est pas un tableau, c'est HTMLCollection Utiliser une boucle for serait mieux.

et depuis HTMLCollection s sont des objets de type tableau vous pouvez call Array#forEach sur elle comme ceci

Array.prototype.forEach.call(input, ShowResults);
7
répondu grape_mao 2017-12-01 00:57:18

c'est parce que l'entrée est une collection html. la collection html n'a pas de forEach.

vous pouvez facilement le convertir en tableau par Tableau.prototype.tranche

exemple:

function ShowResults(value, index, ar) {
            alert(index);
        }
        var input = document.getElementsByTagName("input");
        alert(input.length);
input = Array.prototype.slice.call(input)
        input.forEach(ShowResults);

http://jsfiddle.net/fPuKt/1 /

4
répondu Daniel Dykszak 2015-10-22 09:08:05

la raison, cela ne fonctionne pas est parce que ' getElementsByTagName " retourne un objet de type tableau plutôt qu'un tableau réel. Si vous n'êtes pas au courant, voici à quoi ils ressemblent tous les deux: -

var realArray = ['a', 'b', 'c'];
var arrayLike = {
  0: 'a',
  1: 'b',
  2: 'c',
  length: 3
};

ainsi, puisque les objets de type tableau héritent de ' objet.prototype 'au lieu de' tableau.prototype ', cela signifie que les objets de type tableau ne peuvent pas accéder aux méthodes de prototype des tableaux courants. comme forEach(), push(), map(), filter(), et slice().

Espère que ça aide!

4
répondu Naman Sancheti 2017-07-08 11:36:54

HTMLCollections n'a pas les mêmes méthodes que les tableaux. Vous pouvez vérifier cette chose par ce basculement dans la console javascript de votre navigateur.

var elements = document.getElementsByClassName('some-class');
'forEach' in elements;

et la console retournera true si elements (dans ce cas) a une méthode appelée forEach à appeler.

2
répondu Andrés Torres 2013-10-11 18:28:28

dans ES6 vous pouvez utiliser l'opérateur spread pour convertir une collection HTML en tableau. voir la question pourquoi ne puis-je pas utiliser Array.un aperçu d'une collection D'éléments Javascript?

input = [...input]
input.forEach(ShowResults)
1
répondu inostia 2017-05-23 11:55:11

j'ai fait ceci:

HTMLCollection.prototype.map = Array.prototype.map;

vous pouvez maintenant utiliser la carte sur chaque HTMLCollection .

document.getElementsByTagName("input").map(
    input => console.log(input)
);
1
répondu Toni Almeida 2018-01-07 00:46:54