Пошук уроків, статей та іншого контенту
Навчитеся знаходити елементи за селекторами та безпечно перевіряти результат пошуку.
DOM — це об’єктне представлення HTML-документа в пам’яті браузера. JavaScript може знаходити елементи DOM, читати їхні властивості та змінювати сторінку.
Наприклад, за допомогою JavaScript можна:
знайти кнопку та додати їй обробник події;
отримати текст заголовка;
знайти всі елементи списку;
змінити класи, атрибути або вміст елементів.
Для пошуку найчастіше використовують CSS-селектори.
<h1 id="title">Мій список</h1>
<ul class="tasks">
<li class="task">Вивчити DOM</li>
<li class="task">Написати код</li>
</ul>У цьому прикладі:
#title — селектор елемента з ідентифікатором title;
.tasks — селектор елемента з класом tasks;
.task — селектор елементів із класом task;
li — селектор усіх елементів <li>.
querySelectorМетод querySelector() знаходить перший елемент, який відповідає CSS-селектору.
const title = document.querySelector('#title');
console.log(title);Результатом буде елемент:
<h1 id="title">Мій список</h1>Метод працює з будь-якими CSS-селекторами:
const title = document.querySelector('#title');
const list = document.querySelector('.tasks');
const firstTask = document.querySelector('.task');
const button = document.querySelector('button');Якщо відповідного елемента немає, querySelector() повертає null.
const missingElement = document.querySelector('.does-not-exist');
console.log(missingElement); // nullТому не можна одразу звертатися до властивостей результату, не перевіривши його:
const button = document.querySelector('.save');
// Помилка, якщо кнопки немає в HTML:
// button.textContent = 'Збережено';Безпечний варіант:
const button = document.querySelector('.save');
if (button) {
button.textContent = 'Збережено';
}querySelectorAllМетод querySelectorAll() знаходить усі елементи, які відповідають селектору.
const tasks = document.querySelectorAll('.task');
console.log(tasks);Метод повертає об’єкт NodeList. Якщо збігів немає, повертається порожній NodeList, а не null.
const elements = document.querySelectorAll('.does-not-exist');
console.log(elements.length); // 0Перебрати знайдені елементи можна за допомогою for...of:
const tasks = document.querySelectorAll('.task');
for (const task of tasks) {
console.log(task.textContent);
}Також можна використати метод forEach():
const tasks = document.querySelectorAll('.task');
tasks.forEach((task) => {
task.classList.add('found');
});Оскільки querySelectorAll() завжди повертає колекцію, перевіряти її на null не потрібно. За потреби можна перевірити кількість знайдених елементів:
const tasks = document.querySelectorAll('.task');
if (tasks.length > 0) {
console.log('Знайдено завдання:', tasks.length);
}getElementByIdДля пошуку елемента за ідентифікатором можна використати getElementById():
const title = document.getElementById('title');
if (title) {
console.log(title.textContent);
}На відміну від CSS-селектора querySelector(), цей метод отримує лише значення id, без символу #.
// Правильно
document.getElementById('title');
// Правильно
document.querySelector('#title');
// Неправильно для getElementById
document.getElementById('#title');Якщо елемента з таким ідентифікатором немає, метод повертає null.
getElementById() зручний для простого пошуку за id, а querySelector() — коли потрібні складніші CSS-селектори.
Методи пошуку можна викликати не лише на document, а й на конкретному елементі.
<section class="news">
<h2>Новини</h2>
<p class="text">Перша новина</p>
</section>
<section class="articles">
<h2>Статті</h2>
<p class="text">Перша стаття</p>
</section>const newsSection = document.querySelector('.news');
if (newsSection) {
const text = newsSection.querySelector('.text');
if (text) {
console.log(text.textContent);
}
}У цьому прикладі пошук .text виконується лише всередині .news. Це корисно, коли на сторінці є багато однакових класів.
Можна також знайти всі елементи певного типу всередині контейнера:
const newsSection = document.querySelector('.news');
if (newsSection) {
const paragraphs = newsSection.querySelectorAll('p');
for (const paragraph of paragraphs) {
console.log(paragraph.textContent);
}
}querySelector() і querySelectorAll() підтримують комбіновані CSS-селектори.
const firstImportantTask = document.querySelector('.tasks .task.important');
const links = document.querySelectorAll('nav a');
const checkedTasks = document.querySelectorAll('input[type="checkbox"]:checked');Приклади селекторів:
.menu .item — елемент .item усередині .menu;
ul > li — елементи <li>, які є безпосередніми дочірніми елементами <ul>;
input[type="text"] — текстові поля введення;
.task.completed — елемент, який має одночасно класи task і completed;
button[data-action="save"] — кнопка з атрибутом data-action="save".
Селектор має бути правильним CSS-селектором. Якщо селектор некоректний, браузер згенерує помилку.
Під час пошуку потрібно враховувати, що елемент може бути відсутнім у DOM.
const form = document.querySelector('.contact-form');
if (form) {
console.log('Форму знайдено');
form.classList.add('ready');
} else {
console.log('Форму не знайдено');
}Замість if (form) можна явно перевірити form !== null:
const form = document.querySelector('.contact-form');
if (form !== null) {
form.classList.add('ready');
}Для початкового коду варіант if (form) зазвичай коротший і достатньо зрозумілий.
Якщо потрібно лише безпечно прочитати властивість, можна використати оператор ?.:
const titleText = document.querySelector('#title')?.textContent;
console.log(titleText);Якщо заголовка немає, помилки не виникне. Результатом буде undefined.
Однак оператор ?. не замінює перевірку в усіх ситуаціях. Якщо після пошуку потрібно виконати кілька дій, краще використати if:
const button = document.querySelector('.save-button');
if (button) {
button.textContent = 'Збережено';
button.disabled = true;
}Для результату querySelectorAll() перевіряють кількість елементів:
const buttons = document.querySelectorAll('button');
if (buttons.length === 0) {
console.log('Кнопок немає');
} else {
console.log('Кількість кнопок:', buttons.length);
}JavaScript має виконувати пошук після того, як потрібні елементи вже створені браузером.
Якщо скрипт розташований перед HTML-елементом, пошук може повернути null:
<script>
const title = document.querySelector('#title');
// На цьому етапі заголовок може бути ще не створений.
console.log(title);
</script>
<h1 id="title">Заголовок</h1>Є кілька способів уникнути цієї проблеми.
Найпростіший спосіб — розмістити <script> перед закривальним тегом body:
<body>
<h1 id="title">Заголовок</h1>
<script src="script.js"></script>
</body>На момент виконання скрипту HTML-елементи вище вже існуватимуть у DOM.
DOMContentLoadedІнший спосіб — запустити код після побудови DOM:
document.addEventListener('DOMContentLoaded', () => {
const title = document.querySelector('#title');
if (title) {
console.log(title.textContent);
}
});Подія DOMContentLoaded відбувається після того, як браузер завантажив і розібрав HTML-документ.
Нижче наведено повний приклад сторінки. Програма знаходить заголовок, кнопку та всі завдання. Після натискання кнопки вона змінює текст заголовка і додає клас усім пунктам списку.
<!doctype html>
<html lang="uk">
<head>
<meta charset="UTF-8">
<title>Пошук елементів у DOM</title>
<style>
.completed {
text-decoration: line-through;
color: gray;
}
</style>
</head>
<body>
<h1 id="title">Мої завдання</h1>
<ul class="tasks">
<li class="task">Вивчити CSS-селектори</li>
<li class="task">Вивчити методи DOM</li>
<li class="task">Написати практичний приклад</li>
</ul>
<button class="complete-button" type="button">
Завершити всі завдання
</button>
<script>
const title = document.querySelector('#title');
const tasks = document.querySelectorAll('.task');
const completeButton = document.querySelector('.complete-button');
if (title && completeButton) {
completeButton.addEventListener('click', () => {
title.textContent = 'Усі завдання завершено';
for (const task of tasks) {
task.classList.add('completed');
}
});
}
</script>
</body>
</html>У прикладі:
querySelector('#title') знаходить заголовок.
querySelectorAll('.task') знаходить усі завдання.
querySelector('.complete-button') знаходить кнопку.
Перевірка if (title && completeButton) гарантує, що потрібні елементи існують.
Цикл for...of додає клас кожному завданню.
querySelector()повертає перший знайдений елемент;
приймає CSS-селектор;
повертає null, якщо елемент не знайдено.
const element = document.querySelector('.item');querySelectorAll()повертає всі знайдені елементи;
приймає CSS-селектор;
повертає NodeList, яка може бути порожньою.
const elements = document.querySelectorAll('.item');getElementById()шукає елемент за id;
приймає значення id без символу #;
повертає null, якщо елемент не знайдено.
const element = document.getElementById('item');nullconst title = document.querySelector('#missing');
// Помилка, якщо елемента немає:
// console.log(title.textContent);Безпечний варіант:
const title = document.querySelector('#missing');
if (title) {
console.log(title.textContent);
}# у getElementById()// Неправильно
document.getElementById('#title');
// Правильно
document.getElementById('title');querySelector() поверне всі елементи// Буде знайдено лише перший елемент .task
const firstTask = document.querySelector('.task');Для всіх елементів потрібно використовувати querySelectorAll():
const allTasks = document.querySelectorAll('.task');textContent для всієї колекціїconst tasks = document.querySelectorAll('.task');
// Це не прочитає текст кожного завдання окремо
console.log(tasks.textContent);Потрібно перебрати колекцію:
const tasks = document.querySelectorAll('.task');
for (const task of tasks) {
console.log(task.textContent);
}// Неправильно: відсутня крапка перед назвою класу
const item = document.querySelector('item');Якщо item — це клас, потрібна крапка:
const item = document.querySelector('.item');Якщо item — це ідентифікатор, потрібен символ #:
const item = document.querySelector('#item');Якщо код виконується раніше, ніж потрібний елемент з’явився в DOM, результатом може бути null. Розміщуйте скрипт після HTML або використовуйте DOMContentLoaded.
Створіть заголовок із id="page-title" і знайдіть його за допомогою getElementById().
Створіть три абзаци з класом description і виведіть текст кожного абзацу в консоль.
Знайдіть кнопку з класом delete-button. Якщо кнопки немає, виведіть повідомлення Кнопку не знайдено.
Створіть список товарів і знайдіть усі елементи з класом product лише всередині цього списку.
Додайте обробник події кнопці, який змінює текст усіх знайдених елементів.
DOM дає JavaScript доступ до HTML-елементів сторінки.
querySelector() повертає перший елемент за CSS-селектором.
querySelectorAll() повертає всі елементи за CSS-селектором.
getElementById() знаходить елемент за ідентифікатором без символу #.
Якщо одиничний елемент не знайдено, результатом буде null.
Перед зверненням до властивостей знайденого елемента його потрібно безпечно перевірити.
Для querySelectorAll() перевіряють length і перебирають колекцію.
Пошук можна виконувати всередині конкретного елемента, а не лише в усьому document.
Скрипт потрібно запускати після побудови DOM.