Кратко
Секция статьи "Кратко"HTMLCollection
и NodeList
— это очень похожие на массив коллекции. Они хранят элементы веб-страницы (узлы DOM). NodeList
может хранить любые типы узлов, а HTMLCollection
— только узлы HTML элементов. К элементам коллекций можно обращаться по индексу, но у них нет привычных методов массива.
HTMLCollection
возвращают методы getElementsByTagName
и getElementsByClassName
.
NodeList
возвращают методы querySelectorAll
и childNodes
.
Полный список всех методов, возвращающих типы NodeList
или HTMLCollection
можно узнать в стандарте DOM.
Как понять
Секция статьи "Как понять"HTMLCollection
возвращают методы, которые работают с DOM — представлением HTML-кода страницы в JavaScript.
Полученная один раз коллекция всегда остаётся актуальной — JavaScript будет обновлять её в случае, если на странице появляется подходящий элемент. Поэтому HTMLCollection
называют «живой» коллекцией.
Например, единожды получив коллекцию мы можем не заботиться о её поддержке:
NodeList
работает почти так же, как и HTMLCollection
.
Разница:
NodeList
может хранить любые типы узлов, например текстовые узлы и комментарии, аHTMLCollection
— только узлы HTML элементов;HTMLCollection
позволяет обращаться к элементам не только по индексу, но и по имени с помощью методаnamedItem
;NodeList
может быть не только «живой» коллекцией, но и статической. Такая коллекция не обновляется при появлении на странице новых элементов.
«Живой» NodeList
возвращают методы getElementsByName
и childNodes
.
Статический NodeList
возвращает метод querySelectorAll
.
На практике
Секция статьи "На практике"🛠 Используй индексы для получения отдельных элементов коллекции:
let paragraphs = document.getElementsByTagName("p")console.log(paragraphs[0])
let paragraphs = document.getElementsByTagName("p") console.log(paragraphs[0])
🛠 Если нужно обойти все элементы в цикле, то можно написать классический цикл for
:
let paragraphs = document.getElementsByTagName("p")for (let i = 0; i < paragraphs.length; ++i) { console.log(paragraphs[i].id) // печатаем значение атрибута id элемента}
let paragraphs = document.getElementsByTagName("p") for (let i = 0; i < paragraphs.length; ++i) { console.log(paragraphs[i].id) // печатаем значение атрибута id элемента }
Другой вариант — воспользоваться синтаксисом for
:
let paragraphs = document.getElementsByTagName("p")for (let item of paragraphs) { console.log(item.id)}
let paragraphs = document.getElementsByTagName("p") for (let item of paragraphs) { console.log(item.id) }
🛠 Когда пишешь цикл с HTMLCollection
убедись, что подходящие элементы не добавляются или удаляются со страницы в момент работы цикла. Так как коллекция живая, её обновление во время цикла может создать бесконечный цикл.
🛠 Если очень нужны методы массива, то преобразуй HTMLCollection
или NodeList
в массив с помощью Array
.
let paragraphs = document.getElementsByTagName("p")let array = Array.from(paragraphs)console.log(array.pop())
let paragraphs = document.getElementsByTagName("p") let array = Array.from(paragraphs) console.log(array.pop())
Такое преобразование обычно не требуется. Подумай, точно ли оно подходит под твою задачу.