Поиск элементов в DOM: querySelector и друзья
Содержание
О проверке кода. Примеры не запускались в браузере — в отличие от материалов по Node.js с фактическим выводом. Говорим прямо, а не ставим бейдж «проверено».
Первый шаг любой работы со страницей — найти нужный элемент. В современном JavaScript для этого есть универсальная пара методов. Разберём их и типичные ошибки.
querySelector: первый по селектору
document.querySelector('#header'); // по id
document.querySelector('.card'); // первый с классом card
document.querySelector('ul li.active'); // вложенный CSS-селектор
document.querySelector('[data-id]'); // по атрибуту
querySelector принимает любой CSS-селектор — тот же синтаксис, что в стилях — и возвращает первый совпавший элемент. Это универсальный инструмент: он заменяет старые getElementById, getElementsByClassName и getElementsByTagName одним методом с гибким синтаксисом.
Старый getElementById('header') по-прежнему работает и чуть быстрее, но querySelector('#header') делает то же и вписывается в единый стиль.
querySelectorAll: все элементы
const cards = document.querySelectorAll('.card'); // NodeList всех .card
cards.length; // сколько нашлось
cards[0]; // первый
cards.forEach(card => { // NodeList умеет forEach
card.classList.add('visible');
});
querySelectorAll возвращает все совпавшие элементы в виде NodeList — похожей на массив коллекции. У неё есть length, доступ по индексу и forEach, но нет map, filter, reduce. Для них коллекцию превращают в настоящий массив:
const titles = [...document.querySelectorAll('.card')] // NodeList → массив
.map(card => card.textContent); // теперь map доступен
Обязательно: проверка на null
// ❌ упадёт, если элемента нет
const btn = document.querySelector('.submit');
btn.addEventListener('click', handler); // TypeError, если btn === null
// ✅ проверяем перед использованием
const btn = document.querySelector('.submit');
if (btn) {
btn.addEventListener('click', handler);
}
// или через опциональную цепочку
document.querySelector('.submit')?.addEventListener('click', handler);
querySelector возвращает null, если элемент не найден — из-за опечатки в селекторе или потому что скрипт выполнился до появления элемента в DOM. Обращение к свойству null роняет скрипт с cannot read property of null. Проверка на null (или опциональная цепочка ?.) обязательна — это одна из самых частых ошибок начинающих.
Поиск внутри элемента
const card = document.querySelector('.card');
// искать ТОЛЬКО внутри card, а не по всей странице
const title = card.querySelector('.title');
const buttons = card.querySelectorAll('button');
querySelector можно вызвать не только на document, но и на любом элементе — тогда поиск идёт только внутри него. Это важно для компонентов: находите карточку, потом её заголовок внутри — не рискуя зацепить чужой .title со страницы. Ограничение области поиска делает код надёжнее.
querySelector
Один элемент
- Возвращает ПЕРВЫЙ совпавший
- Или
null, если не найден - Для конкретного элемента
- Проверять на null!
querySelectorAll
Коллекция
- Возвращает ВСЕ в NodeList
- Пустой NodeList, если ничего
- Есть forEach, нет map/filter
[...list]для методов массива
Что дальше с найденным элементом
Найдя элемент, с ним обычно делают одно из:
const el = document.querySelector('.card');
el.textContent; // прочитать/задать текст
el.classList.add('active'); // управлять классами
el.classList.toggle('open'); // переключить класс
el.getAttribute('data-id'); // прочитать атрибут
el.style.color = 'red'; // инлайн-стиль (лучше классы)
Это уже работа с элементом: чтение и изменение содержимого, классов, атрибутов. Классы через classList предпочтительнее прямого style — стилизацию оставляют CSS. Дальше обычно идёт навешивание событий и создание новых элементов.
Смежные темы: события DOM — реакция на клики; создание элементов — добавление на страницу; операторы — проверка на null. Полный список — в уроках JavaScript.