W moim JSFiddle po prostu próbuję iterować po tablicy elementów. Tablica nie jest pusta, o czym świadczą instrukcje log. Jednak wezwanie do wywołania forEach
(niezbyt pomocnego) błędu „Uncught TypeError
: undefined
is not a function”.
Muszę robić coś głupiego; Co ja robię źle?
Mój kod:
var arr = document.getElementsByClassName('myClass');
console.log(arr);
console.log(arr[0]);
arr.forEach(function(v, i, a) {
console.log(v);
});
.myClass {
background-color: #FF0000;
}
<div class="myClass">Hello</div>
javascript
foreach
Jer
źródło
źródło
arr
nie jest tablicą, ale plikiemHTMLCollection
. Nie ma tych samych metod, co tablica. developer.mozilla.org/en-US/docs/Web/API/… . Oto nawet post SO na ten temat: stackoverflow.com/questions/13433799/ ...[1,2,3].forEach(function(v,i,a) { console.log(v); });
jest w porządku. Jaka jest różnica między tym a tablicą w moim przykładzie?arr instanceof Array
rezultaciefalse
nie może korzystać z żadnych prototypowych metodArray
obiektu, takich jak Array.prototype.forEach () .arr
jest HTMLCollection i obiektem przypominającym tablicę (ale nie dziedziczy po nim ani nie tworzy instancjiArray
). W związku z tym standardowafor
pętla będzie działać, ponieważ po prostu iteruje po indeksie obiektu i nie jest prototypemArray
.Odpowiedzi:
Dzieje się tak , ponieważ
document.getElementsByClassName
zwraca HTMLCollection , a nie tablicę.Na szczęście jest to obiekt przypominający tablicę (co wyjaśnia, dlaczego jest rejestrowany tak, jakby był obiektem i dlaczego można iterować za pomocą standardowej
for
pętli), więc możesz to zrobić:[].forEach.call(document.getElementsByClassName('myClass'), function(v,i,a) {
W ES6 (w nowoczesnych przeglądarkach lub z Babel) możesz również użyć,
Array.from
który buduje tablice z obiektów podobnych do tablic:Array.from(document.getElementsByClassName('myClass')).forEach(v=>{
lub rozłóż obiekt podobny do tablicy na tablicę:
[...document.getElementsByClassName('myClass'))].forEach(v=>{
źródło
arguments
jest jeden. Obiekty jQuery to kolejne. Możesz zrobić to sam:var a = {"0": "str1", "1": "str2", length: 2}
querySelectorAll('.myClass')
powinno działać. Nadal czekam na dodanie iteratorów do interfejsu API NodeList. :-(Array.prototype.forEach
, nie pozwoli ci tego zrobić. Jeśli masz to wymaganie później, użyj standardowejfor
pętli lub jeśli chcesz użyć obiektu tablicy, użyjArray.prototype.every
lubArray.prototype.some
(zauważ jednak, że wszystkie / niektóre nie są obsługiwane w IE8 lub mniej)splice
w tej definicji, ale kiedy chcę być bardziej „podobny do tablicy”, aby móc używaćmap
,filter
itd., Dołączam ją. Prosta iteracja przy użyciuforEach
nie wymagasplice
.Spróbuj tego, powinno działać:
<html> <head> <style type="text/css"> </style> </head> <body> <div class="myClass">Hello</div> <div class="myClass">Hello</div> <script type="text/javascript"> var arr = document.getElementsByClassName('myClass'); console.log(arr); console.log(arr[0]); arr = [].slice.call(arr); //I have converted the HTML Collection an array arr.forEach(function(v,i,a) { console.log(v); }); </script> <style type="text/css"> .myClass { background-color: #FF0000; } </style> </body> </html>
źródło
w przypadku, gdy chcesz uzyskać dostęp do identyfikatora każdego elementu określonej klasy, możesz wykonać następujące czynności:
Array.from(document.getElementsByClassName('myClass')).forEach(function(element) { console.log(element.id); });
źródło