Chcę iterować niektóre elementy DOM, robię to:
document.getElementsByClassName( "myclass" ).forEach( function(element, index, array) {
//do stuff
});
ale pojawia się błąd:
document.getElementsByClassName („moja_klasa”). forEach nie jest funkcją
Używam Firefoksa 3, więc wiem, że oba getElementsByClassName
i Array.forEach
są obecne. Działa to dobrze:
[2, 5, 9].forEach( function(element, index, array) {
//do stuff
});
Czy wynika z getElementsByClassName
tablicy? Jeśli nie, co to jest?
źródło
[].forEach.call(elsArray, function () {...})
.querySelectorAll
Metoda zwraca jednak NodeList.document.getElementsByClassName()
powinien zwrócićHTMLCollection
(który jest bardzo podobny, ale nie NodeList). Dzięki za zwrócenie uwagi na błąd.HTMLCollection
wskazówkę. Teraz w końcu mogę użyćHTMLCollection.prototype.forEach = Array.prototype.forEach;
w moim kodzie.Możesz użyć
Array.from
do konwersji kolekcji na tablicę, co jest o wiele czystsze niżArray.prototype.forEach.call
:W starszych przeglądarkach, które nie obsługują
Array.from
, musisz użyć czegoś takiego jak Babel.ES6 dodaje również tę składnię:
Restrukturyzacja spoczynkowa
...
działa na wszystkich obiektach podobnych do tablicy, nie tylko na samych tablicach, a następnie do tworzenia tablicy na podstawie wartości używana jest stara, dobra składnia tablicy.Podczas gdy funkcja alternatywna
querySelectorAll
(która sprawia, że jestgetElementsByClassName
przestarzała) zwraca kolekcję, która maforEach
natywnie, innych metod takich jakmap
lubfilter
brak, więc ta składnia jest nadal przydatna:źródło
Lub możesz użyć,
querySelectorAll
która zwraca NodeList :Obsługiwane przez nowoczesne przeglądarki (w tym Edge, ale nie IE):
Czy mogę używać querySelectorAll
NodeList.prototype.forEach ()
MDN: Document.querySelectorAll ()
źródło
Edycja: Mimo że typ zwrotu zmienił się w nowych wersjach HTML (patrz zaktualizowana odpowiedź Tim Down), poniższy kod nadal działa.
Jak powiedzieli inni, jest to lista NodeList. Oto kompletny, działający przykład, który możesz wypróbować:
Działa to w IE 9, FF 5, Safari 5 i Chrome 12 w Win 7.
źródło
Wynikiem
getElementsByClassName()
nie jest tablica, ale obiekt podobny do tablicy . W szczególności jest to nazywane anHTMLCollection
, z którym nie należy mylićNodeList
( który ma własnąforEach()
metodę ).Jednym prostym sposobem przy użyciu ES2015 do konwersji obiektu typu tablicowego do użytku z
Array.prototype.forEach()
tym, o którym jeszcze nie wspomniano, jest użycie operatora lub składni spreadu :źródło
Nie
Podobnie jak w przypadku wszystkich metod DOM zwracających wiele elementów, jest to NodeList, patrz https://developer.mozilla.org/en/DOM/document.getElementsByClassName
źródło
Jak już powiedziano,
getElementsByClassName
zwraca HTMLCollection , który jest zdefiniowany jakoWcześniej niektóre przeglądarki zwracały zamiast tego NodeList .
Różnica jest ważna, ponieważ DOM4 definiuje teraz NodeList s jako iterowalny.
Zgodnie z projektem Web IDL ,
Oznacza to, że jeśli chcesz użyć
forEach
, możesz użyć metody DOM, która zwraca NodeList , jakquerySelectorAll
.Uwaga: nie jest to jeszcze szeroko obsługiwane. Zobacz także metodę forEach dla Node.childNodes?
źródło
forEach in not a function
document.querySelectorAll(...).forEach is not a function
Nie
Array
zwraca ani zwraca NodeList .źródło
Jest to bezpieczniejszy sposób:
źródło
getElementsByClassName
zwraca HTMLCollection w nowoczesnych przeglądarkach.który jest obiektem podobnym do tablicy podobnym do argumentów, które można iterować przez
for...of
pętlę, zobacz poniżej, co mówi o tym MDN doc:przykład
źródło
error TS2488: Type 'HTMLCollectionOf<Element>' must have a '[Symbol.iterator]()' method that returns an iterator.
Oto test, który utworzyłem na jsperf: https://jsperf.com/vanillajs-loop-through-elements-of-class
Najbardziej udoskonaloną wersją w Chrome i Firefox jest stara dobra pętla for w połączeniu z document.getElementsByClassName:
W Safari ten wariant jest zwycięzcą:
Jeśli chcesz mieć najbardziej wydajny wariant dla wszystkich przeglądarek, może to być ten:
źródło