DOM, часть 3 из 3. Поиск элементов
09.05.2022
Теги: DOM • Frontend • HTML • JavaScript • Web-разработка • Документ • Коллекция • Теория
Свойства навигации по DOM хороши, когда элементы расположены рядом. А что, если нет? Как получить произвольный элемент страницы? Для этого в DOM есть дополнительные методы поиска — getElementById, getElementsByTagName, getElementsByClassName, querySelector, querySelectorAll.
document.getElementById
Если у элемента есть атрибут id, то мы можем получить его вызовом document.getElementById(id), где бы он ни находился.
<div id="elem">Какой-то контент</div> <script> // получить элемент let elem = document.getElementById('elem'); // сделать фон красным elem.style.background = 'red'; </script>
getElementById можно вызвать только для объекта document. Он осуществляет поиск по id по всему документу.
elem.querySelectorAll
Самый универсальный метод поиска — это elem.querySelectorAll(css), он возвращает все элементы внутри elem, удовлетворяющие данному CSS-селектору.
<ul> <li>Этот</li> <li>тест</li> </ul> <ul> <li>полностью</li> <li>пройден</li> </ul> <script> let elements = document.querySelectorAll('ul > li:last-child'); for (let elem of elements) { alert(elem.textContent); // тест, пройден } </script>
elem.querySelector
Метод elem.querySelector(css) возвращает первый элемент внутри elem, соответствующий данному CSS-селектору. Иначе говоря, результат такой же, как при вызове elem.querySelectorAll(css)[0], но он сначала найдёт все элементы, а потом возьмёт первый, в то время как elem.querySelector найдёт только первый и остановится. Это быстрее, кроме того, его короче писать.
elem.closest
Предки элемента — это родитель, родитель родителя, его родитель и так далее. Вместе они образуют цепочку иерархии от элемента до вершины. Метод elem.closest(css) ищет ближайшего предка, который соответствует CSS-селектору. Сам элемент также включается в поиск.
Другими словами, метод closest поднимается вверх от элемента и проверяет каждого из родителей. Если он соответствует селектору, поиск прекращается. Метод возвращает либо предка, либо null, если такой элемент не найден.
<h1>Содержание</h1> <div class="contents"> <ul class="book"> <li class="chapter">Глава 1</li> <li class="chapter">Глава 2</li> </ul> </div> <script> let chapter = document.querySelector('.chapter'); // <li class="chapter">Глава 1</li> alert(chapter.closest('.book')); // <ul class="book"> alert(chapter.closest('.contents')); // <div class="contents"> alert(chapter.closest('h1')); // null (потому что h1 — не предок) </script>
elem.matches
Предыдущие методы искали по DOM. Метод elem.matches(css) ничего не ищет, а проверяет, удовлетворяет ли elem CSS-селектору, и возвращает true или false. Метод удобен, когда мы перебираем элементы (например, в массиве) и пытаемся выбрать те из них, которые нас интересуют.
<a href="http://example.com/file.zip">...</a> <a href="http://yandex.ru">...</a> <script> // может быть любая коллекция вместо document.body.children for (let elem of document.body.children) { if (elem.matches('a[href$="zip"]')) { alert('Ссылка на архив: ' + elem.href); } } </script>
elem.contains
Метод elem.contains(node) возвращает логическое значение, указывающее, является ли node потомком elem, то есть сам узел, один из его прямых потомков, один из детей его детей и так далее.
elem.getElementsByTagName
Метод elem.getElementsByTagName(tag) ищет элементы с данным тегом и возвращает их коллекцию. Передав * вместо тега, можно получить всех потомков.
elem.getElementsByClassName
Метод elem.getElementsByClassName(className) возвращает элементы, которые имеют данный CSS-класс.
Живые коллекции
Методы getElementsByTagName и getElementsByClassName возвращают живую коллекцию. Такие коллекции всегда отражают текущее состояние документа и автоматически обновляются при его изменении.
<div>Первый div</div> <script> let divs = document.getElementsByTagName('div'); alert(divs.length); // 1 </script> <div>Второй div</div> <script> alert(divs.length); // 2 </script>
Напротив, querySelectorAll возвращает статическую коллекцию. Это похоже на фиксированный массив элементов.
<div>Первый div</div> <script> let divs = document.querySelectorAll('div'); alert(divs.length); // 1 </script> <div>Второй div</div> <script> alert(divs.length); // 1 </script>
Длина статической коллекции не изменилась после появления нового div в документе.
HTMLCollection и NodeList
HTMLCollection и NodeList — это очень похожие на массив коллекции. Они хранят элементы веб-страницы (узлы DOM). NodeList может хранить любые типы узлов, а HTMLCollection — только узлы HTML элементов. К элементам коллекций можно обращаться по индексу, но у них нет привычных методов массива.
HTMLCollectionвозвращают методыgetElementsByTagName,getElementsByClassNameи свойствоchildrenNodeListвозвращают методыquerySelectorAll,getElementsByNameи свойствоchildNodes
Полученная один раз HTMLCollection всегда остаётся актуальной — поэтому ее часто называют «живой» коллекцией. Это значит, что JavaScript будет обновлять её в случае, если на странице появляется новый подходящий элемент.
NodeList может быть не только «живой» коллекцией, но и статической. Такая коллекция не обновляется при появлении на странице новых элементов. «Живой» NodeList возвращают метод getElementsByName и свойство childNodes. Метод querySelectorAll возвращает статический NodeList.
- DOM, часть 1 из 3. Навигация по элементам
- DOM, часть 4 из 4. Атрибуты и свойства
- DOM, часть 2 из 3. Изменение документа
- JavaScript. HTMLCollection и NodeList
- Браузерные события, часть 5 из 5. Генерация пользовательских событий
- Браузерные события, часть 4 из 5. Действие браузера по умолчанию
- Браузерные события, часть 3 из 5. Делегирование
Поиск: DOM • Frontend • HTML • JavaScript • Web-разработка • Документ • Коллекция • Теория