J'essaie de parcourir tous les éléments renvoyés par getElementsByTagName("input")
à l'aide de forEach. Des idées pour lesquelles cela ne fonctionne pas dans 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>
Vous devez convertir la liste de noeuds 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 la boucle.
for(i = 0;i < input.length; i++)
{
ShowResults(input[i].value);
}
et remplacez la fonction ShowResults par:
function ShowResults(value) {
alert(value);
}
Oui, ES6:
const children = [...parent.getElementsByTagName('tag')];
children.forEach((child) => { /* Do something; */ });
Puisque input
n’est pas un tableau, c’est HTMLCollection
Utiliser une boucle for
serait préférable.
Et puisque HTMLCollection
s sont des objets de type tableau, vous pouvez call
Array#forEach
dessus comme ça
Array.prototype.forEach.call(input, ShowResults);
C'est parce que l'entrée est une collection HTML. La collection HTML n'a pas forEach.
vous pouvez facilement le convertir en tableau par Array.prototype.slice
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);
La raison, cela ne fonctionne pas, c'est parce que 'getElementsByTagName' renvoie un objet semblable à un tableau plutôt qu'un tableau réel. Au cas où vous ne le sauriez pas, voici à quoi ressemblent les deux: -
var realArray = ['a', 'b', 'c'];
var arrayLike = {
0: 'a',
1: 'b',
2: 'c',
length: 3
};
Ainsi, comme les objets ressemblant à Array héritent de 'Object.prototype' au lieu de 'Array.prototype', cela signifie que les objets ressemblant à Array ne peuvent pas accéder au prototype Array commun. des méthodes telles que forEach (), Push (), map (), filter () et slice ().
J'espère que ça t'as aidé!
getElementsByTagName
renvoie un HTMLCollection
, qui n'a pas de méthode forEach
. Mais il existe un simple Tweak qui vous permettra d’itérer avec forEach
sans créer un tableau intermédiaire: utilisez querySelectorAll
à la place. querySelectorAll
retourne un NodeList
, et les navigateurs modernes ont un NodeList.prototype.forEach
méthode:
document.querySelectorAll('input')
.forEach((input) => {
console.log(input.value);
});
<input type="text" value="foo">
<input type="text" value="bar">
L’utilisation de querySelectorAll
présente un autre avantage: elle accepte les chaînes de requête séparées par des virgules, qui sont beaucoup plus souples et précises que les noms de balises. Par exemple, la chaîne de requête
.container1 > span, .container2 > span
ne fera correspondre que span
s qui sont des enfants d'éléments avec une classe de container1
ou container2
:
document.querySelectorAll('.container1 > span, .container2 > span')
.forEach((span) => {
span.classList.add('highlight');
});
.highlight {
background-color: yellow;
}
<div class="container1">
<span>foo</span>
<span>bar</span>
</div>
<div class="container2">
<span>baz</span>
</div>
<div class="container3">
<span>buzz</span>
</div>
Si vous voulez utiliser NodeList.prototype.forEach
sur les anciens navigateurs n’ayant pas la méthode intégrée, ajoutez simplement un polyfill . L'extrait suivant fonctionnera sur IE11:
// Polyfill:
if (window.NodeList && !NodeList.prototype.forEach) {
NodeList.prototype.forEach = function(callback, thisArg) {
thisArg = thisArg || window;
for (var i = 0; i < this.length; i++) {
callback.call(thisArg, this[i], i, this);
}
};
}
// Main code:
document.querySelectorAll('.container1 > span, .container2 > span')
.forEach(function(span) {
span.classList.add('highlight');
});
.highlight {
background-color: yellow;
}
<div class="container1">
<span>foo</span>
<span>bar</span>
</div>
<div class="container2">
<span>baz</span>
</div>
<div class="container3">
<span>buzz</span>
</div>
HTMLCollections n'a pas les mêmes méthodes que les tableaux. Vous pouvez vérifier cette chose en la glissant 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.
Dans ES6, vous pouvez utiliser l'opérateur spread
pour convertir une HtmlCollection en un tableau. voir cette question Pourquoi ne puis-je pas utiliser Array.forEach sur une collection d'éléments Javascript?
input = [...input]
input.forEach(ShowResults)
J'ai fait ça:
HTMLCollection.prototype.map = Array.prototype.map;
Vous pouvez maintenant utiliser la carte sur chaque HTMLCollection
.
document.getElementsByTagName("input").map(
input => console.log(input)
);