Поиск элементов в 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 против querySelectorAll

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.

Частые вопросы

Чем querySelector отличается от getElementById?
querySelector принимает любой CSS-селектор (’.card’, ‘#id’, ‘ul li’) и возвращает первый совпавший элемент. getElementById ищет только по id и чуть быстрее. На практике querySelector универсальнее и используется чаще.
В чём разница между querySelector и querySelectorAll?
querySelector возвращает первый найденный элемент или null. querySelectorAll возвращает все совпавшие в виде NodeList — статической коллекции, которую можно перебрать через forEach или for…of.
Почему querySelector возвращает null?
Если элемент не найден или скрипт выполнился до загрузки этой части страницы. Поэтому результат всегда проверяют перед использованием: обращение к свойству null вызывает ошибку ‘cannot read property of null’.
Можно ли применить forEach к результату querySelectorAll?
Да, у NodeList есть forEach. Но нет map, filter и reduce — для них NodeList сначала превращают в массив через […list] или Array.from(list), а потом применяют методы массива.
Как искать элемент внутри другого элемента?
Вызвать querySelector на самом элементе, а не на document: card.querySelector(’.title’) найдёт только внутри card. Это ограничивает поиск нужным контейнером и делает код надёжнее.