DOM, часть 3 из 3. Поиск элементов

09.05.2022

Теги: DOMFrontendHTMLJavaScriptWeb-разработкаДокументКоллекцияТеория

Свойства навигации по 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 и свойство children
  • NodeList возвращают методы querySelectorAll, getElementsByName и свойство childNodes

Полученная один раз HTMLCollection всегда остаётся актуальной — поэтому ее часто называют «живой» коллекцией. Это значит, что JavaScript будет обновлять её в случае, если на странице появляется новый подходящий элемент.

NodeList может быть не только «живой» коллекцией, но и статической. Такая коллекция не обновляется при появлении на странице новых элементов. «Живой» NodeList возвращают метод getElementsByName и свойство childNodes. Метод querySelectorAll возвращает статический NodeList.

Поиск: DOM • Frontend • HTML • JavaScript • Web-разработка • Документ • Коллекция • Теория

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.