JS: итерация по результату getElementsByClassName с использованием массива.инструкция foreach
Я хочу перебрать некоторые элементы DOM, я делаю это:
document.getElementsByClassName( "myclass" ).forEach( function(element, index, array) {
//do stuff
});
но я получаю сообщение об ошибке: документ.getElementsByClassName ("myclass").forEach-это не функция
Я использую Firefox 3, поэтому я знаю, что оба getElementsByClassName
и Array.forEach
присутствуют. Это прекрасно работает:
[2, 5, 9].forEach( function(element, index, array) {
//do stuff
});
результат getElementsByClassName
массив? Если нет, то что это?
8 ответов:
нет. Как указано в DOM4, это
HTMLCollection
(по крайней мере, в современных браузерах. Старые браузеры вернулиNodeList
).во всех современных браузерах (почти все другие IE forEach метод, передавая ему список элементов (будь то
HTMLCollection
илиNodeList
) какthis
значение:var els = document.getElementsByClassName("myclass"); Array.prototype.forEach.call(els, function(el) { // Do stuff here console.log(el.tagName); }); // Or [].forEach.call(els, function (el) {...});
можно использовать
Array.from
преобразовать коллекцию в массив, который намного чище, чемArray.prototype.forEach.call
:Array.from(document.getElementsByClassName("myclass")).forEach( function(element, index, array) { // do stuff } );
в старых браузерах, которые не поддерживают
Array.from
, вам нужно использовать что-то вроде Вавилона.
ES6 также добавляет этот синтаксис:
[...document.getElementsByClassName("myclass")].forEach( (element, index, array) => { // do stuff } );
отдых деструктурирование с
...
работает на всех массив-как объекты, а не только массивы сами, то старый добрый синтаксис массива используется, чтобы создать массив из ценности.
в то время как альтернативная функция
querySelectorAll
(который вроде как делаетgetElementsByClassName
obsolete) возвращает коллекцию, которая имеетforEach
изначально, другие методы, например,map
илиfilter
отсутствуют, поэтому этот синтаксис еще пригодится:[...document.querySelectorAll(".myclass")].map( (element, index, array) => { // do stuff } ); [...document.querySelectorAll(".myclass")].map(element => element.innerHTML);
Edit: хотя тип возврата изменился в новых версиях HTML (см. обновленный ответ Тима Дауна), приведенный ниже код все еще работает.
как говорили другие, это NodeList. Вот полный, рабочий пример, который вы можете попробовать:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <script> function findTheOddOnes() { var theOddOnes = document.getElementsByClassName("odd"); for(var i=0; i<theOddOnes.length; i++) { alert(theOddOnes[i].innerHTML); } } </script> </head> <body> <h1>getElementsByClassName Test</h1> <p class="odd">This is an odd para.</p> <p>This is an even para.</p> <p class="odd">This one is also odd.</p> <p>This one is not odd.</p> <form> <input type="button" value="Find the odd ones..." onclick="findTheOddOnes()"> </form> </body> </html>
это работает в IE 9, FF 5, Safari 5 и Chrome 12 на Win 7.
или вы можете использовать
querySelectorAll
возвращает NodeList:document.querySelectorAll('.myclass').forEach(...)
поддерживается современными браузерами (включая Edge, но не IE):
могу ли я использовать querySelectorAll
список узлов.прототип.forEach ()
является ли результат getElementsByClassName массивом?
нет
если нет, то что это?
Как и все методы DOM, которые возвращают несколько элементов, это NodeList, см. https://developer.mozilla.org/en/DOM/document.getElementsByClassName
результат
getElementsByClassName()
- это не массив, а массив-как объект. В частности, это называетсяHTMLCollection
, не путать сNodeList
(былоforEach()
метод).один простой способ с ES2015 конвертировать массив-подобный объект для использования с
Array.prototype.forEach()
это еще не было упомянуто, чтобы использовать оператор распространения или распространение синтаксис:const elementsArray = document.getElementsByClassName('myclass'); [...elementsArray].forEach((element, index, array) => { // do something });
как уже было сказано,
getElementsByClassName
возвращает a HTMLCollection, который определяется как[Exposed=Window] interface HTMLCollection { readonly attribute unsigned long length; getter Element? item(unsigned long index); getter Element? namedItem(DOMString name); };
ранее некоторые браузеры возвращали a NodeList вместо.
[Exposed=Window] interface NodeList { getter Node? item(unsigned long index); readonly attribute unsigned long length; iterable<Node>; };
разница важна, потому что DOM4 теперь определяет NodeLists как iterable.
по данным web IDL проект
объекты, реализующие интерфейс, который объявляется чтобы быть итерируемым поддержка повторяется для получения последовательности значений.
Примечание: в привязке языка ECMAScript, интерфейс, который является iterable будет иметь "записи", "forEach", "ключи", "значения" и @@iterator свойства объект-прототип интерфейса.
это означает, что если вы хотите использовать
forEach
, вы можете использовать метод DOM, который возвращает a NodeList, какquerySelectorAll
.document.querySelectorAll(".myclass").forEach(function(element, index, array) { // do stuff });
обратите внимание, что это еще не получило широкой поддержки. Также смотрите метод forEach узла.childNodes?
Он не возвращает
Array
возвращает NodeList.