Найти несколько DOM-элементов иполучить кним доступ изJavaScript
можно разными
способами:querySelectorAll
,getElementsByTagName
,children
итак
далее. Витоге вкаждом случае будет
возвращенаколлекция сущность, которая похожа
намассив объектов, нопри этом имнеявляется, насамом деле это набор
DOM-элементов. Стоит учесть, что фактически разные методы
возвращают разные коллекции:
-
HTMLCollection
коллекция непосредственно HTML-элементов. -
NodeList
коллекция узлов, более абстрактное понятие. Например, вDOM-дереве есть нетолько узлы-элементы, нотакже текстовые узлы, узлы-комментарии идругие, поэтомуNodeList
может содержать другие типы узлов.
При работе сDOM-элементами в нашем случае тип коллекции значительной роли неиграет, поэтому для удобства будем рассматривать ихкак одну сущность коллекцию.
Вовремя работы сколлекциями можно столкнуться споведением, которое покажется странным, если незнать один нюанс они бываютживыми(динамическими) инеживыми(статическими). Тоесть либо реагируют налюбое изменение DOM, либо нет. Вид коллекции зависит отспособа, спомощью которого она получена. Рассмотрим напримере.
Разница между живыми инеживыми коллекциями
Допустим, вразметке есть список книг:
<ul class="books"> <li class="book book--one"></li> <li class="book book--two"></li> <li class="book book--three"></li></ul>
Для взаимодействия скнигами получим спомощью JavaScript список
всех нужных элементов. Чтобы вдальнейшем увидеть разницу между
видами коллекций, используем разные способы поиска элементов
свойствоchildren
иметодquerySelectorAll
:
const booksList = document.querySelector('.books');const liveBooks = booksList.children;// Выведем все дочерние элементы списка .booksconsole.log(liveBooks);
const notLiveBooks = document.querySelectorAll('.book');// Выведем коллекцию, содержащую все элементы с классом bookconsole.log(notLiveBooks);
Пока никакой разницы невидно. Вобоих
случаяхconsole.log
выведет одни итеже элементы. Ночто,
если попробовать удалить изDOM одну изкниг?
const booksList = document.querySelector('.books');const liveBooks = booksList.children;// Удалим первую книгуliveBooks[0].remove();// Получим 2console.log(liveBooks.length);// Получим элемент book--two, который теперь стал первым в коллекцииconsole.log(liveBooks[0]);
const notLiveBooks = document.querySelectorAll('.book');// Удалим первую книгуnotLiveBooks[0].remove();// Получим 3console.log(notLiveBooks.length);// Получим ссылку на удалённый элемент book--oneconsole.log(notLiveBooks[0]);
Впервом случае информация околичестве элементов внутри коллекции
автоматически обновилась после удаления одного элемента изDOM эта
коллекция живая. Вовтором случае
впеременнойnotLiveBooks
хранится первоначальное
состояние коллекции, которое было актуально намомент вызова
методаquerySelectorAll
. Эта коллекция неживая, она
ничего незнает обизменении DOM. При этом доступна ссылка
наудалённый элементbook--one
, которого фактически
больше нет вDOM.
Другие способы получить коллекцию
Кромеchildren
иquerySelectorAll
есть
другие способы поиска DOM-элементов:
-
getElementsByTagName(tag)
находит все элементы сзаданным тегом, -
getElementsByClassName(className)
находит все элементы сзаданным классом, -
getElementsByName(name)
находит все элементы сзаданным атрибутомname
.
Все эти методы возвращают живые коллекции. Они используются
реже, потому что вбольшинстве случаев удобнее
применятьquerySelectorAll
, номогут встречаться встаром
коде.
Как использовать
Для решения большинства задач можно ограничиться неживыми коллекциями. Ноесли нужно сохранить ссылку нареальное состояние DOM понадобится живая коллекция. Это удобно втех случаях, когда программе нужно постоянно манипулировать списком элементов, которые могут регулярно удаляться идобавляться. Хороший пример задачи втаск-трекере. Спомощью живой коллекции можно хранить именно тезадачи, которые фактически существуют вданный момент времени.
Структура инекоторые свойства коллекции имеют много общего
смассивом. Например, унеё тоже есть свойствоlength
,
иэлементы коллекции можно перебирать вциклеfor...of
,
потому что это перечисляемая сущность. Но, как упоминалось ранее,
коллекции невовсём похожи наобычные массивы. Сколлекциями
неработают такие методы массивов,
какpush
,splice
идругие. Для
ихиспользования нужно преобразовать коллекцию вмассив например,
спомощью методаArray.from
:
const booksList = document.querySelector('.books');const books = booksList.children;// Выведет обычный массив с элементами из коллекции booksconsole.log(Array.from(books));
При этом нужно помнить массив статичен, поэтому при таком преобразовании теряются преимущества живых коллекций.
В HTML Academy есть курсы для опытных разработчиков по анимациям для фронтендеров, вёрстке email-рассылок и Vue.js. Приходите, чтобы улучшить навыки и узнать много нового о веб-разработке а там со всеми этими знаниями и до сеньора недалеко.