Поиск элементов на странице
Браузер превращает HTML-код страницы в набор объектов: каждый тег становится объектом со свойствами и методами. Эта структура называется DOM (Document Object Model — объектная модель документа). Через неё JavaScript читает и меняет страницу.
Примеры в этой главе — маленькие страницы. Под кодом показан результат: сама страница и всё, что выведено через console.log().
querySelector
Вся страница доступна через объект document. Его метод querySelector() находит элемент по CSS-селектору:
<h1>Привет, мир!</h1>
<script>
const heading = document.querySelector('h1');
console.log(heading.textContent); // Привет, мир!
</script>Свойство textContent хранит текст элемента.
Селекторы
Селекторы здесь такие же, как в CSS: имя тега, # для идентификатора и точка для класса. Работают и сложные селекторы, например ul li или input[type="email"]:
<p id="intro">Вступление</p>
<p class="note">Заметка</p>
<script>
console.log(document.querySelector('#intro').textContent); // Вступление
console.log(document.querySelector('.note').textContent); // Заметка
</script>Если подходящих элементов несколько, querySelector() возвращает первый.
querySelectorAll
Метод querySelectorAll() возвращает все подходящие элементы. Результат можно перебрать циклом for...of, а количество узнать через length:
<ul>
<li>Чай</li>
<li>Кофе</li>
<li>Сок</li>
</ul>
<script>
const items = document.querySelectorAll('li');
console.log(items.length); // 3
for (const item of items) {
console.log(item.textContent);
}
</script>Это не массив, а похожий на него список. Если нужны map() или filter(), превратите его в массив: Array.from(items).
Поиск внутри элемента
Оба метода есть не только у document, но и у любого элемента. Тогда поиск идёт только внутри него:
<ul id="drinks">
<li>Чай</li>
</ul>
<ul id="food">
<li>Хлеб</li>
<li>Сыр</li>
</ul>
<script>
const food = document.querySelector('#food');
console.log(food.querySelectorAll('li').length); // 2
</script>Поиск вверх: closest
Метод closest() ищет в обратную сторону — среди родителей элемента, то есть тегов, внутри которых он находится. Он возвращает ближайшего родителя, подходящего под селектор:
<div class="card">
<h2>Ноутбук</h2>
<button>Купить</button>
</div>
<script>
const button = document.querySelector('button');
const card = button.closest('.card');
console.log(card.querySelector('h2').textContent); // Ноутбук
</script>Если ничего не найдено
Когда подходящего элемента нет, querySelector() возвращает null:
<p>На этой странице нет заголовка.</p>
<script>
const heading = document.querySelector('h1');
console.log(heading); // null
</script>Обращение к свойству у null вызывает ошибку, поэтому результат поиска стоит проверять: if (heading) { ... }.
Частая ошибка
Скрипт выполняется в том месте страницы, где он написан. Если поместить его перед элементом, элемент ещё не создан, и поиск вернёт null. Поэтому скрипты размещают в конце страницы, после всей разметки, или добавляют тегу script атрибут defer — тогда браузер выполнит его после загрузки страницы.