Pracowałem nad krótkim skryptem do zmiany <abbr>
wewnętrznego tekstu elementów, ale okazało się, że nodelist
nie ma on forEach
metody. Wiem, że nodelist
to nie dziedziczy po Array
, ale czy nie wydaje się, że forEach
byłoby to przydatne? Czy jest jakiś szczególny problem realizacja nie jestem świadomy, który uniemożliwia dodanie forEach
do nodelist
?
Uwaga: zdaję sobie sprawę, że Dojo i jQuery mają forEach
w jakiejś formie swoje listy węzłów. Nie mogę też używać ze względu na ograniczenia.
javascript
arrays
dom
foreach
Węże i kawa
źródło
źródło
Odpowiedzi:
NodeList ma teraz forEach () we wszystkich głównych przeglądarkach
Zobacz nodeList forEach () w MDN .
Oryginalna odpowiedź
Żadna z tych odpowiedzi nie wyjaśnia, dlaczego NodeList nie dziedziczy po tablicy, co pozwala jej mieć
forEach
i całą resztę.Odpowiedź znajduje się w tym wątku es-dyskusji . Krótko mówiąc, łamie sieć:
Oznacza to, że jakiś kod zrobił coś podobnego
if (x instanceof Array) { otherArray.concat(x); } else { doSomethingElseWith(x); }
Jednak
concat
„prawdziwe” tablice (nie instancje Array) będą traktować inaczej niż inne obiekty:[1, 2, 3].concat([4, 5, 6]) // [1, 2, 3, 4, 5, 6] [1, 2, 3].concat(4) // [1, 2, 3, 4]
oznacza to, że powyższy kod zepsuł się, gdy
x
był NodeList, ponieważ wcześniej poszedł w dółdoSomethingElseWith(x)
ścieżki, podczas gdy później poszedł w dółotherArray.concat(x)
ścieżki, co zrobiło coś dziwnego, ponieważx
nie był prawdziwą tablicą.Przez pewien czas istniała propozycja
Elements
klasy, która byłaby prawdziwą podklasą Array i miałaby służyć jako „nowa lista NodeList”. Jednak zostało to usunięte ze standardu DOM , przynajmniej na razie, ponieważ nie było to jeszcze możliwe do zaimplementowania z różnych powodów technicznych i specyfikacji.źródło
NodeList now has forEach() in all major browsers
wydaje się sugerować, że IE nie jest główną przeglądarką. Mam nadzieję, że to prawda w przypadku niektórych osób, ale nie jest to prawda dla mnie (jeszcze).Możesz to zrobić
Array.prototype.forEach.call (nodeList, function (node) { // Your code here. } );
źródło
Array.prototype.forEach.call
można[].forEach.call
Array.prototype.forEach.call
, to tworzenie pustej tablicy i używanie jejforEach
metody.Możesz rozważyć utworzenie nowej tablicy węzłów.
var nodeList = document.getElementsByTagName('div'), nodes = Array.prototype.slice.call(nodeList,0); // nodes is an array now. nodes.forEach(function(node){ // do your stuff here. });
Uwaga: to jest tylko lista / tablica odniesień do węzłów, które tutaj tworzymy, bez zduplikowanych węzłów.
nodes[0] === nodeList[0] // will be true
źródło
Array.prototype.forEach.call(nodeList, fun)
.var forEach = Array.prototype.forEach.call(nodeList, callback);
. Teraz możesz po prostu zadzwonićforEach(nodeList, callback);
Nigdy nie mów nigdy, jest rok 2016, a
NodeList
obiekt ma zaimplementowanąforEach
metodę w najnowszym chrome (v52.0.2743.116).Jest za wcześnie, aby używać go w produkcji, ponieważ inne przeglądarki jeszcze tego nie obsługują (testowane FF 49), ale myślę, że wkrótce zostanie to ustandaryzowane.
źródło
Array.prototype.slice.call(nodelist).forEach(…)
to, co jest standardowe i działa w starych przeglądarkach.Krótko mówiąc, implementacja tej metody jest konfliktem projektowym.
Z MDN:
Źródło: https://developer.mozilla.org/en-US/docs/DOM/NodeList (przewiń w dół do Dlaczego nie mogę używać forEach lub mapować na NodeList? )
źródło
myNodeList --> NodeList.prototype --> Array.prototype --> Object.prototype --> null
:?Jeśli chcesz używać forEach na NodeList, po prostu skopiuj tę funkcję z Array:
NodeList.prototype.forEach = Array.prototype.forEach;
To wszystko, teraz możesz go używać w taki sam sposób, jak w przypadku tablicy:
document.querySelectorAll('td').forEach(function(o){ o.innerHTML = 'text'; });
źródło
W ES2015 możesz teraz używać
forEach
metody do nodeList.document.querySelectorAll('abbr').forEach( el => console.log(el));
Zobacz łącze MDN
Jeśli jednak chcesz użyć kolekcji HTML lub innych obiektów podobnych do tablic, w es2015 możesz użyć
Array.from()
metody method. Ta metoda przyjmuje obiekt przypominający tablicę lub obiekt iterowalny (w tym nodeList, kolekcje HTML, ciągi znaków itp.) I zwraca nową instancję Array. Możesz go używać w ten sposób:const elements = document.getElementsByTagName('abbr'); Array.from(elements).forEach( el => console.log(el));
Ponieważ
Array.from()
metoda jest shimmable, możesz jej użyć w kodzie es5 w ten sposóbvar elements = document.getElementsByTagName('abbr'); Array.from(elements).forEach( function(el) { console.log(el); });
Szczegółowe informacje można znaleźć na stronie MDN .
Aby sprawdzić aktualną obsługę przeglądarek .
LUB
Innym sposobem na es2015 jest użycie operatora spreadu.
[...document.querySelectorAll('abbr')].forEach( el => console.log(el));
Operator rozprzestrzeniania MDN
Operator rozprzestrzeniania - obsługa przeglądarki
źródło
Moje rozwiązanie:
//foreach for nodeList NodeList.prototype.forEach = Array.prototype.forEach; //foreach for HTML collection(getElementsByClassName etc.) HTMLCollection.prototype.forEach = Array.prototype.forEach;
źródło
NodeList jest częścią DOM API. Spójrz na powiązania ECMAScript, które mają również zastosowanie do JavaScript. http://www.w3.org/TR/DOM-Level-2-Core/ecma-script-binding.html . NodeList i właściwość długości tylko do odczytu i funkcja elementu (indeksu) do zwracania węzła.
Odpowiedź brzmi: musisz iterować. Nie ma alternatywy. Foreach nie zadziała. Pracuję z powiązaniami API Java DOM i mam ten sam problem.
źródło
NodeList.forEach(function(item, index, nodeList) { // code block here });
W IE użyj odpowiedzi akuhna :
[].forEach.call(NodeList, function(item, index, array) { // code block here });
źródło