Поиск элементов - первый шаг почти в любой DOM-задаче. В современном JavaScript чаще всего используют два метода:
querySelector- вернуть первый найденный элементquerySelectorAll- вернуть все найденные элементы
Оба метода принимают CSS-селектор, то есть строку, похожую на то, что пишется в CSS.
1) querySelector: найти один элемент
querySelector возвращает первый элемент, который подходит под селектор. Если ничего не найдено - вернется null.
const title = document.querySelector("h1");
console.log(title);
Примеры селекторов:
document.querySelector("#header"); // по id
document.querySelector(".card"); // по классу
document.querySelector("button"); // по тегу
document.querySelector("a.link"); // тег + класс
document.querySelector(".menu a"); // вложенность
document.querySelector("input[type='text']"); // атрибут
Проверка на null полезна, если элемент может отсутствовать:
const banner = document.querySelector(".banner");
if (banner) {
banner.textContent = "Hello";
}
2) querySelectorAll: найти несколько элементов
querySelectorAll возвращает NodeList. Это коллекция, похожая на массив, но это не массив.
const links = document.querySelectorAll("a");
console.log(links);
console.log(links.length);
NodeList удобно перебирать через for...of:
const links = document.querySelectorAll("a");
for (const link of links) {
console.log(link.href);
}
Или через forEach:
const buttons = document.querySelectorAll("button");
buttons.forEach((btn) => {
btn.classList.add("is-ready");
});
3) Поиск внутри элемента, а не по всей странице
У каждого DOM-элемента тоже есть querySelector и querySelectorAll. Это важно, когда нужно искать не по всей странице, а внутри конкретного блока.
const card = document.querySelector(".card");
const title = card.querySelector(".card-title");
const actions = card.querySelectorAll("button");
console.log(title);
console.log(actions.length);
Такой подход уменьшает риск “поймать” чужой элемент с таким же классом где-то в другом месте.
4) Частые селекторы, которые встречаются в DOM-скриптах
По id
document.querySelector("#app");
По классу
document.querySelector(".modal");
По data-атрибуту
HTML:
<button data-action="save">Save</button>
JavaScript:
const btn = document.querySelector("[data-action='save']");
console.log(btn);
Можно искать и просто по наличию атрибута:
const items = document.querySelectorAll("[data-id]");
console.log(items.length);
Комбинации
document.querySelector(".list .item"); // элемент .item внутри .list
document.querySelector("form input[name='q']"); // input внутри form по name
5) Как понять, что именно вернул поиск
Полезно помнить:
querySelector->Element | nullquerySelectorAll->NodeList(может быть пустым)
const a = document.querySelector(".missing");
console.log(a); // null
const b = document.querySelectorAll(".missing");
console.log(b.length); // 0
6) NodeList не равен массиву
Частая ошибка - пытаться сразу вызвать на NodeList методы массива вроде map или filter.
const nodes = document.querySelectorAll("a");
console.log(typeof nodes.map); // undefined
Если нужно использовать методы массива, можно сделать настоящий массив:
const nodes = document.querySelectorAll("a");
const links = Array.from(nodes);
const hrefs = links.map((a) => a.href);
console.log(hrefs);
Иногда достаточно forEach или for...of, без преобразования.
7) Почему селектор “не работает”
1) Элемента нет в DOM на момент поиска
Если скрипт выполняется слишком рано, элемент еще не создан, и поиск вернет null.
document.addEventListener("DOMContentLoaded", () => {
const title = document.querySelector("h1");
console.log(title);
});
2) Неправильный селектор
Например, забыта точка у класса:
document.querySelector("card"); // ищет тег <card>
document.querySelector(".card"); // ищет класс card
3) На странице несколько похожих элементов, но нужен конкретный
Если нужен элемент внутри блока, лучше искать от контейнера:
const modal = document.querySelector(".modal");
const closeBtn = modal.querySelector("[data-action='close']");
Что стоит запомнить
querySelectorвозвращает первый элемент илиnull.querySelectorAllвозвращаетNodeList, который может быть пустым.- Оба метода принимают CSS-селектор.
- Поиск удобно ограничивать контейнером:
container.querySelector(...). NodeListне массив, но его можно перебирать черезfor...ofиforEach, а при необходимости превращать в массив черезArray.from.