querySelectorAll и NodeList
querySelectorAllвозвращает статичную NodeList всех элементов, соответствующих CSS-селектору; в отличие от живых HTMLCollection, NodeList не обновляется автоматически при изменении DOM.
Зачем нужно
querySelectorAll — универсальный метод поиска элементов, принимающий любой валидный CSS-селектор. Это позволяет заменить несколько специализированных методов (getElementById, getElementsByClassName, getElementsByTagName) одним. Понимание разницы между «живыми» и «статичными» коллекциями критично для предотвращения багов в динамических интерфейсах.
Где используется
- Поиск элементов по любому CSS-селектору (вложенность, комбинаторы, псевдоклассы)
- Батч-обработка группы элементов
- Снимок DOM в конкретный момент времени
- Чтение списка элементов без риска мутации при итерации
Основной контент
Базовое использование
// Все элементы с классом .item
const items = document.querySelectorAll('.item');
// NodeList поддерживает forEach напрямую
items.forEach(item => item.classList.add('active'));
// Сложные селекторы
const checked = document.querySelectorAll('input[type="checkbox"]:checked');
const navLinks = document.querySelectorAll('nav > ul > li > a');
const first3 = document.querySelectorAll('li:nth-child(-n+3)');
querySelector — первый совпадающий
// Возвращает первый элемент или null
const modal = document.querySelector('.modal');
if (modal) {
modal.style.display = 'block';
}
// Поиск внутри элемента
const form = document.querySelector('#login-form');
const emailInput = form.querySelector('input[type="email"]');
NodeList vs HTMLCollection
const list = document.getElementById('myList');
// HTMLCollection — живая
const live = list.getElementsByTagName('li');
// NodeList — статичная
const static_ = list.querySelectorAll('li');
// Добавляем новый элемент
const li = document.createElement('li');
list.appendChild(li);
console.log(live.length); // увеличилось
console.log(static_.length); // не изменилось
// NodeList не является массивом
console.log(static_ instanceof Array); // false
// Но поддерживает forEach, entries, keys, values
static_.forEach(el => console.log(el.textContent));
// Конвертация в массив для map, filter, reduce
const arr = Array.from(static_);
const texts = arr.map(el => el.textContent);
Производительность
// Поиск внутри элемента эффективнее, чем глобальный
const section = document.querySelector('#main-section');
const links = section.querySelectorAll('a'); // ищет только внутри section
// Для частых обращений — кэшируем результат
const buttons = document.querySelectorAll('.btn');
// Вызываем querySelectorAll один раз, не в цикле
buttons.forEach(btn => {
btn.addEventListener('click', handleClick);
});
Частые ошибки
querySelectorAllне возвращает массив — методыmap,filter,reduceнедоступны напрямую. ИспользуйтеArray.fromили spread[...].- Неверный CSS-селектор выбрасывает
SyntaxError— оберните вызов вtry/catchпри динамическом формировании селектора. - Кэширование статичной NodeList — если DOM изменился, NodeList устарела. Для динамического контента пересчитывайте коллекцию или используйте живую HTMLCollection.