1. Почему нужны новые методы поиска?
Вспомним коротко:
getElementById('id') — ищет один элемент по уникальному идентификатору.
getElementsByClassName('class') — находит все элементы с данным классом.
getElementsByTagName('tag') — находит все элементы с данным тегом.
Но что если нам нужно найти:
- Первый <input> внутри определённого блока?
- Все элементы с классом .button, которые лежат внутри <nav>?
- Элемент с классом .active, который ещё и является ссылкой (<a>)?
С помощью старых методов это превращается в головоломку. Вот тут и приходят на помощь современные методы поиска!
2. Метод querySelector: ищем ОДИН элемент по CSS-селектору
Как работает
querySelector — это универсальный способ найти первый элемент, подходящий под CSS-селектор.
Синтаксис:
let элемент = document.querySelector('селектор');
- Возвращает первый найденный элемент или null, если не нашёл ничего.
- Можно использовать любые CSS-селекторы: по тегу, классу, id, атрибуту, вложенности и их комбинации.
Примеры использования
Поиск по классу
let firstButton = document.querySelector('.button');
// Найдёт первый элемент с классом "button"
Поиск по id
let mainHeader = document.querySelector('#header');
// Найдёт элемент с id="header"
Поиск по тегу
let firstParagraph = document.querySelector('p');
// Найдёт первый <p> на странице
Вложенные селекторы
let navLink = document.querySelector('nav .link');
// Найдёт первый элемент с классом "link" внутри <nav>
Поиск по атрибуту
let checkedInput = document.querySelector('input[type="checkbox"]:checked');
// Найдёт первый отмеченный чекбокс
Комбинированный селектор
let special = document.querySelector('.menu li.active > a');
// Найдёт первую ссылку <a> внутри <li class="active"> в .menu
Пример: добавим в наше мини-приложение
Допустим, у нас есть такой HTML:
<ul id="todo-list">
<li class="task">Сделать домашку</li>
<li class="task important">Позвонить маме</li>
<li class="task">Погулять с собакой</li>
</ul>
Найдём первую важную задачу:
let importantTask = document.querySelector('#todo-list .important');
console.log(importantTask.textContent); // "Позвонить маме"
3. Метод querySelectorAll: ищем ВСЕ элементы по CSS-селектору
Как работает
querySelectorAll ищет все элементы, подходящие под селектор, и возвращает их в виде специальной коллекции — NodeList.
Синтаксис:
let элементы = document.querySelectorAll('селектор');
- Возвращает NodeList — похож на массив, но не совсем (об этом чуть позже).
- Если ничего не найдено — вернёт пустой список, а не null.
Примеры использования
Все элементы с классом
let allTasks = document.querySelectorAll('.task');
console.log(allTasks.length); // 3
Все ссылки внутри навигации
let navLinks = document.querySelectorAll('nav a');
Все отмеченные чекбоксы
let checkedInputs = document.querySelectorAll('input[type="checkbox"]:checked');
Все элементы с определённым атрибутом
let imagesWithAlt = document.querySelectorAll('img[alt]');
Вложенные и комбинированные селекторы
let menuItems = document.querySelectorAll('.menu > li.active');
Пример: перебираем задачи
let tasks = document.querySelectorAll('#todo-list .task');
tasks.forEach(function(task, index) {
console.log(`Задача ${index + 1}: ${task.textContent}`);
});
Выведет:
Задача 1: Сделать домашку
Задача 2: Позвонить маме
Задача 3: Погулять с собакой
4. Селекторы: как писать и что можно использовать
Оба метода используют CSS-селекторы. Если вы знакомы с CSS, то уже знаете большую часть синтаксиса. Вот краткая шпаргалка:
| Селектор | Что найдёт | Пример |
|---|---|---|
|
Все элементы с классом | |
|
Элемент с указанным id | |
|
Все элементы с тегом | , |
|
Теги с указанным классом | |
|
Все потомки внутри родителя | |
|
Только прямых детей | |
|
Элементы с атрибутом | |
|
Элементы с атрибутом и значением | |
|
Первый ребёнок | |
|
Последний ребёнок | |
|
N-й ребёнок | |
|
Ссылки, начинающиеся на https | |
|
Все отмеченные чекбоксы/радиокнопки | |
Можно комбинировать селекторы, как в CSS. Главное — не забывайте про кавычки, если используете их в JS!
5. Отличие querySelector и querySelectorAll
- querySelector — всегда возвращает один (первый подходящий) элемент или null.
- querySelectorAll — возвращает NodeList (коллекцию всех подходящих элементов).
Пример:
let firstTask = document.querySelector('.task'); // Только первая задача
let allTasks = document.querySelectorAll('.task'); // Все задачи
6. Как использовать querySelector и querySelectorAll внутри других элементов
Оба метода можно вызывать не только у document, но и у любого DOM-элемента! Это позволяет искать элементы не по всей странице, а только внутри определённого блока.
Пример
<div class="user-panel">
<button class="action">Лайк</button>
<button class="action">Поделиться</button>
</div>
<div class="admin-panel">
<button class="action">Удалить</button>
</div>
let userPanel = document.querySelector('.user-panel');
let userButtons = userPanel.querySelectorAll('.action');
// Найдёт только кнопки внутри user-panel
let adminPanel = document.querySelector('.admin-panel');
let adminButton = adminPanel.querySelector('.action');
// Найдёт только одну кнопку внутри admin-panel
7. Особенности NodeList: чем отличается от массива?
Результат querySelectorAll — это NodeList. Он похож на массив (есть length, можно обращаться по индексу), но это не полноценный массив JS:
- Можно использовать forEach для перебора (в современных браузерах).
- Нельзя напрямую применять методы массивов, такие как map, filter, reduce (придётся сначала преобразовать в настоящий массив).
Преобразование NodeList в массив
let nodeList = document.querySelectorAll('.task');
let array = Array.from(nodeList);
array.map(task => task.textContent.toUpperCase());
8. Практика: добавляем интерактивность в наше мини-приложение
Давайте доработаем наш список задач (todo-list), чтобы при клике на задачу она становилась "выполненной" (например, добавлялся класс .done).
HTML:
<ul id="todo-list">
<li class="task">Сделать домашку</li>
<li class="task important">Позвонить маме</li>
<li class="task">Погулять с собакой</li>
</ul>
JS:
let tasks = document.querySelectorAll('#todo-list .task');
tasks.forEach(function(task) {
task.addEventListener('click', function() {
task.classList.toggle('done');
});
});
Теперь при клике на любую задачу она будет отмечаться как выполненная (или обратно).
CSS (для красоты):
.task.done {
text-decoration: line-through;
color: gray;
}
9. Типичные ошибки при использовании querySelector и querySelectorAll
Ошибка №1: опечатка в селекторе.
Самая частая проблема — неправильно написанный селектор. Например, .menu .item вместо .menu-item, или забыли точку/решётку. Если элемент не находится, проверьте селектор!
Ошибка №2: обращение к несуществующему элементу.
Если querySelector не находит элемент, он вернёт null. Попытка обратиться к свойству такого объекта вызовет ошибку. Всегда проверяйте, что элемент найден:
let el = document.querySelector('.not-exist');
if (el) {
el.textContent = 'Я существую!';
}
Ошибка №3: попытка использовать методы массива на NodeList.
NodeList не поддерживает все методы массива. Например, нельзя сделать nodeList.map(...) — сначала преобразуйте в массив.
Ошибка №4: забыли кавычки вокруг селектора.
Селектор — это строка! Не забудьте кавычки:
document.querySelector(.button); // Ошибка!
document.querySelector('.button'); // Всё ок
Ошибка №5: ожидание "живой" коллекции.
querySelectorAll возвращает статическую коллекцию. Если вы добавите новые элементы после вызова — они не появятся в NodeList. Нужно вызвать метод ещё раз, чтобы получить новые элементы.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ