DOM поиск элементов

Браузер предоставляет набор методов для нахождения DOM-элементов по CSS-селекторам, id, классу или тегу — без этого невозможна любая динамическая работа со страницей.

Зачем нужно

Прежде чем изменить элемент, добавить обработчик событий или прочитать его данные — нужно его найти. Знание методов поиска и их отличий (живые vs. статические коллекции, один vs. все) экономит время при отладке и помогает писать производительный код.

Где используется

  • Получение элементов формы для валидации и чтения значений
  • Навешивание обработчиков событий на кнопки, ссылки, карточки
  • Динамическое обновление текста, классов и атрибутов
  • Работа с компонентами (поиск внутри контейнера)
  • Тестирование через document.querySelector в DevTools

Основной контент

Основные методы

// Один элемент — первый совпавший с CSS-селектором
document.querySelector('.card');
document.querySelector('#submit-btn');
document.querySelector('input[type="email"]');

// Все совпавшие — статический NodeList
document.querySelectorAll('.item');
document.querySelectorAll('li:nth-child(odd)');

// По id — самый быстрый
document.getElementById('header');

// По классу — живая HTMLCollection
document.getElementsByClassName('active');

// По тегу — живая HTMLCollection
document.getElementsByTagName('p');

Поиск внутри элемента

const form = document.querySelector('#login-form');

// Ищет только внутри form, не по всему документу
const emailInput = form.querySelector('input[name="email"]');
const allInputs = form.querySelectorAll('input');

Навигация по дереву

const el = document.querySelector('.item');

el.parentElement;           // родительский элемент
el.children;                // дочерние элементы (HTMLCollection)
el.firstElementChild;       // первый дочерний элемент
el.lastElementChild;        // последний дочерний элемент
el.nextElementSibling;      // следующий сосед
el.previousElementSibling;  // предыдущий сосед
el.closest('.container');   // ближайший предок по CSS-селектору

Живые vs. статические коллекции

// querySelectorAll — статический NodeList, снимок на момент вызова
const staticList = document.querySelectorAll('.item');

// getElementsByClassName — живой, обновляется при изменении DOM
const liveList = document.getElementsByClassName('item');

document.querySelector('.container').innerHTML += '<div class="item"></div>';

console.log(staticList.length); // не изменится
console.log(liveList.length);   // увеличится на 1

Перебор результатов

const items = document.querySelectorAll('.item');

// NodeList поддерживает forEach напрямую
items.forEach(item => {
  item.classList.add('processed');
});

// Для живых коллекций — через Array.from
Array.from(document.getElementsByClassName('card')).forEach(card => {
  console.log(card.textContent);
});

matches и closest

const btn = document.querySelector('button');

// Проверяет, соответствует ли элемент селектору
btn.matches('.primary');        // true / false
btn.matches('[disabled]');

// Поднимается вверх по DOM в поиске предка
btn.closest('form');            // ближайший <form>
btn.closest('[data-modal]');    // ближайший элемент с атрибутом

Частые ошибки

  • querySelector вернул null, скрипт упал — элемент не найден или скрипт запустился до рендеринга DOM. Проверьте наличие элемента или переместите <script> в конец <body> / добавьте defer.
  • Итерация живой HTMLCollection стандартным for...of — старые движки не поддерживают. Используйте Array.from или [...collection].
  • Поиск по всему document вместо контейнера — при повторяющихся компонентах можно случайно получить чужой элемент. Всегда ищите внутри корневого элемента компонента.
  • Путают children и childNodeschildren возвращает только элементы, childNodes включает текстовые узлы и комментарии.

Связанные темы

Ресурсы