Я пытаюсь установить получить идентификатор всех элементов в HTMLCollectionOf
. Я написал следующий код:
var list = document.getElementsByClassName("events");
console.log(list[0].id);
for (key in list) {
console.log(key.id);
}
Но я получил следующий вывод в консоли:
event1
undefined
это не то, что я ожидал. Почему второй вывод консоли, undefined
а первый вывод консоли event1
?
javascript
dom
нейрон
источник
источник
Array.from(document.getElementsByClassName("events")).forEach(function(item) {
Ответы:
В ответ на оригинальный вопрос, вы используете
for/in
неправильно. В вашем кодеkey
есть индекс. Итак, чтобы получить значение из псевдомассива, вам нужно сделать,list[key]
а чтобы получить идентификатор, вам нужноlist[key].id
. Но вы не должны делать это сfor/in
самого начала.Резюме (добавлено в декабре 2018 г.)
Никогда не используйте
for/in
для итерации nodeList или HTMLCollection. Причины, чтобы избежать этого, описаны ниже.Все последние версии современных браузеров (Safari, Firefox, Chrome, Edge) поддерживают
for/of
итерацию в списках DOM, таких какnodeList
илиHTMLCollection
.Вот пример:
Чтобы включить старые браузеры (включая такие, как IE), это будет работать везде:
Пояснение, почему вы не должны использовать
for/in
for/in
предназначен для итерации свойств объекта. Это означает, что он вернет все итерируемые свойства объекта. Хотя может показаться, что он работает для массива (возвращая элементы массива или элементы псевдомассива), он также может возвращать другие свойства объекта, отличные от ожидаемых от элементов, подобных массиву. И, угадайте, что,HTMLCollection
иnodeList
объект или оба могут иметь другие свойства, которые будут возвращены сfor/in
итерацией. Я просто попытался это в Chrome и итерация его так , как вы итерация будет извлекать элементы в списке (индексы 0, 1, 2, и т.д ...), но также будет получатьlength
иitem
свойства.for/in
Итерация просто не будет работать для HTMLCollection.Смотрите http://jsfiddle.net/jfriend00/FzZ2H/ почему вы не можете перебирать в HTMLCollection с
for/in
.В Firefox ваша
for/in
итерация будет возвращать эти элементы (все итерируемые свойства объекта):Надеюсь, теперь вы можете понять, почему вы хотите использовать
for (var i = 0; i < list.length; i++)
вместо этого, чтобы вы просто получили0
,1
и2
в вашей итерации.Ниже приводится эволюция эволюции браузеров за период 2015-2018 гг., Которая дает вам дополнительные способы итерации. В современных браузерах ничего из этого не требуется, поскольку вы можете использовать опции, описанные выше.
Обновление для ES6 в 2015 году
В ES6 добавлено то,
Array.from()
что преобразовать массивоподобную структуру в реальный массив. Это позволяет прямо перечислять список следующим образом:Рабочая демонстрация (в Firefox, Chrome и Edge на апрель 2016 г.): https://jsfiddle.net/jfriend00/8ar4xn2s/
Обновление для ES6 в 2016 году
Теперь вы можете использовать ES6 для / of конструкции с a
NodeList
и aHTMLCollection
, просто добавив это в ваш код:Затем вы можете сделать:
Это работает в текущей версии Chrome, Firefox и Edge. Это работает, потому что он присоединяет итератор Array к прототипам NodeList и HTMLCollection, так что, когда for / of итерирует их, он использует итератор Array для их итерации.
Рабочая демонстрация: http://jsfiddle.net/jfriend00/joy06u4e/ .
Второе обновление для ES6 в декабре 2016 года
По состоянию на декабрь 2016 года
Symbol.iterator
поддержка была встроена в Chrome v54 и Firefox v50, поэтому приведенный ниже код работает сам по себе. Он еще не встроен в Edge.Рабочая демонстрация (в Chrome и Firefox): http://jsfiddle.net/jfriend00/3ddpz8sp/
Третье обновление для ES6 в декабре 2017 года
По состоянию на декабрь 2017 года эта возможность работает в Edge 41.16299.15.0 для «
nodeList
как в»document.querySelectorAll()
, но не для «HTMLCollection
как в»,document.getElementsByClassName()
поэтому вам нужно вручную назначить итератор, чтобы использовать его в Edge дляHTMLCollection
. Это загадка, почему они исправляют один тип коллекции, а не другой. Но вы можете по крайней мере использовать результатdocument.querySelectorAll()
сfor/of
синтаксисом ES6 в текущих версиях Edge сейчас.Я также обновил вышеупомянутый jsFiddle, чтобы он тестировал
HTMLCollection
иnodeList
отдельно, и захватывал выходные данные в самом jsFiddle.Четвертое обновление для ES6 в марте 2018 года
Per mesqueeeb,
Symbol.iterator
поддержка была встроена в Safari, так что вы можете использоватьfor (let item of list)
для любойdocument.getElementsByClassName()
илиdocument.querySelectorAll()
.Пятое обновление для ES6 в апреле 2018 года
По-видимому, поддержка итерации
HTMLCollection
сfor/of
будет приходить в Edge 18 осенью 2018 года.Шестое обновление для ES6 в ноябре 2018 года
Я могу подтвердить, что с Microsoft Edge v18 (которая включена в Windows Update 2018 года) теперь вы можете перебирать HTMLCollection и NodeList с for / of в Edge.
Итак, теперь все современные браузеры содержат встроенную поддержку
for/of
итерации объектов HTMLCollection и NodeList.источник
Вы не можете использовать
for
/in
наNodeList
с илиHTMLCollection
с. Тем не менее, вы можете использовать некоторыеArray.prototype
методы, если вы.call()
их и передать вNodeList
илиHTMLCollection
какthis
.Таким образом , необходимо учитывать следующее в качестве альтернативы jfriend00 игровой
for
петлю :На MDN есть хорошая статья, которая описывает эту технику. Обратите внимание на предупреждение о совместимости браузера:
Таким образом, хотя этот подход удобен,
for
цикл может быть наиболее совместимым с браузером решением.Обновление (30 августа 2014 г.): со временем вы сможете использовать ES6
for
/of
!Это уже поддерживается в последних версиях Chrome и Firefox.
источник
<select multiple>
. Пример:[].map.call(multiSelect.selectedOptions, function(option) { return option.value; })
for ... of
работает.В ES6 вы могли бы сделать что-то вроде
[...collection]
, илиArray.from(collection)
,Например:-
источник
[...row.cells].forEach
row.querySelectorAll('td')
Вы можете добавить эти две строки:
HTMLCollection возвращается getElementsByClassName и getElementsByTagName
NodeList возвращается querySelectorAll
Вот так вы можете сделать forEach:
источник
NodeList
уже естьforEach()
.У меня была проблема с использованием forEach в IE 11, а также Firefox 49
Я нашел обходной путь, как это
источник
Альтернативой
Array.from
является использованиеArray.prototype.forEach.call
для каждого:
Array.prototype.forEach.call(htmlCollection, i => { console.log(i) });
карта:
Array.prototype.map.call(htmlCollection, i => { console.log(i) });
ЭСТ ...
источник
Нет причин использовать функции es6, чтобы избежать
for
зацикливания, если вы используете IE9 или выше.В ES5 есть два хороших варианта. Во-первых, вы можете «одолжить»
Array
,forEach
как упоминает Эван .Но даже лучше ...
Использование
Object.keys()
, что делает естьforEach
и фильтры для «собственных свойств» автоматически.То есть,
Object.keys
по сути, эквивалентно делатьfor... in
с aHasOwnProperty
, но гораздо более плавно.источник
По состоянию на март 2016 года в Chrome 49.0
for...of
работает дляHTMLCollection
:Смотрите здесь документацию .
Но это работает, только если вы применили следующий обходной путь перед использованием
for...of
:То же самое необходимо использовать
for...of
сNodeList
:Я верю / надеюсь
for...of
скоро будет работать без вышеуказанного обходного пути. Открытый вопрос здесь:Обновление: см. Комментарий Expenzor ниже: Это было исправлено по состоянию на апрель 2016 года. Вам не нужно добавлять HTMLCollection.prototype [Symbol.iterator] = Array.prototype [Symbol.iterator]; перебрать HTMLCollection с for ... of
источник
HTMLCollection.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
чтобы перебратьHTMLCollection
сfor...of
.По краю
источник
Простой обходной путь, который я всегда использую
После этого вы можете запустить любые нужные методы Array на выбор
источник
если вы используете более старые версии ES (например, ES5), вы можете использовать
as any
:источник
Вы хотите изменить это на
источник
for (key in list)
Будет возвращать несколько свойствHTMLCollection
, которые не должны быть элементы коллекции.