Пошук уроків, статей та іншого контенту
Розглянете DOM як об’єктне представлення HTML-документа та навчитеся читати його деревоподібну структуру.
DOM (Document Object Model) — це об’єктна модель документа. Браузер створює її, коли завантажує HTML-сторінку.
HTML-файл є текстом, а DOM — структурованим представленням цього тексту у вигляді об’єктів, пов’язаних між собою.
Завдяки DOM JavaScript може:
знаходити HTML-елементи;
читати їхній вміст;
змінювати текст, атрибути та стилі;
додавати й видаляти елементи;
реагувати на дії користувача.
Наприклад, браузер отримує такий HTML:
<h1>Мій сайт</h1>
<p>Вітаємо!</p>Після обробки браузер створює об’єкти DOM для h1, p та тексту всередині них.
DOM має деревоподібну структуру. Кореневим об’єктом документа є document.
Типова HTML-сторінка може бути представлена приблизно так:
document
└── html
├── head
│ └── title
│ └── "Мій сайт"
└── body
├── h1
│ └── "Вітаємо!"
└── p
└── "Це моя сторінка."У цьому дереві:
document — увесь документ;
html — кореневий HTML-елемент;
head і body — дочірні елементи html;
h1 і p — дочірні елементи body;
текст усередині елементів — окремі текстові вузли.
Кожен вузол дерева може мати:
батьківський вузол — вузол на один рівень вище;
дочірні вузли — вузли на один рівень нижче;
сусідні вузли — вузли на тому самому рівні.
Для такого фрагмента:
<body>
<h1>Вітаємо!</h1>
<p>Текст сторінки</p>
</body>body є батьківським елементом для h1 і p;
h1 і p є дочірніми елементами body;
h1 і p є сусідніми елементами;
текст "Вітаємо!" є дочірнім текстовим вузлом h1.
У DOM існують різні типи вузлів. Найчастіше використовують такі:
document представляє всю HTML-сторінку.
console.log(document);Через document можна отримувати доступ до елементів сторінки та працювати з ними.
HTML-теги представлені елементами DOM:
<h1>Заголовок</h1>
<p>Абзац</p>У цьому прикладі h1 і p — елементи.
У JavaScript елемент можна зберегти в змінну:
const heading = document.querySelector('h1');
console.log(heading);Текст усередині елемента є окремим вузлом:
<p>Привіт!</p>Елемент p містить текстовий вузол "Привіт!".
Зазвичай текст читають через властивість textContent:
const paragraph = document.querySelector('p');
console.log(paragraph.textContent);Атрибути описують властивості HTML-елементів:
<a href="/about" class="menu-link">Про нас</a>У цього елемента є атрибути:
href;
class.
Атрибути не є дочірніми вузлами елемента, але доступні через DOM API.
const link = document.querySelector('a');
console.log(link.getAttribute('href'));
console.log(link.getAttribute('class'));querySelectorМетод querySelector повертає перший елемент, який відповідає CSS-селектору.
const title = document.querySelector('h1');
const card = document.querySelector('.card');
const button = document.querySelector('#save-button');У прикладі:
'h1' шукає елемент за назвою тега;
'.card' шукає елемент за класом;
'#save-button' шукає елемент за ідентифікатором.
Якщо відповідного елемента немає, метод повертає null.
const missingElement = document.querySelector('.does-not-exist');
console.log(missingElement); // nullquerySelectorAllМетод querySelectorAll повертає всі елементи, які відповідають селектору.
const paragraphs = document.querySelectorAll('p');
console.log(paragraphs);
console.log(paragraphs.length);Результатом є колекція NodeList. Її можна перебрати методом forEach:
const items = document.querySelectorAll('.item');
items.forEach((item) => {
console.log(item.textContent);
});Для пошуку за ідентифікатором можна використати getElementById:
const form = document.getElementById('signup-form');Для пошуку елементів за назвою тега існує getElementsByTagName:
const headings = document.getElementsByTagName('h2');У сучасному коді querySelector і querySelectorAll часто зручніші, оскільки вони підтримують CSS-селектори.
Після отримання елемента можна переходити до його батьківських і дочірніх вузлів.
parentElementВластивість parentElement повертає батьківський HTML-елемент:
const title = document.querySelector('h1');
console.log(title.parentElement);childrenВластивість children містить дочірні HTML-елементи:
const list = document.querySelector('ul');
console.log(list.children);
console.log(list.children.length);На відміну від childNodes, властивість children ігнорує текстові вузли та повертає лише елементи.
firstElementChild і lastElementChildЦі властивості повертають перший і останній дочірній елемент:
const list = document.querySelector('ul');
console.log(list.firstElementChild);
console.log(list.lastElementChild);nextElementSibling і previousElementSiblingЦі властивості дають змогу перейти до сусідніх елементів:
const firstItem = document.querySelector('li');
console.log(firstItem.nextElementSibling);
console.log(firstItem.previousElementSibling);Якщо сусіднього елемента немає, результатом буде null.
children і childNodesЦі властивості схожі, але працюють по-різному.
children повертає лише дочірні елементи:
const container = document.querySelector('.container');
console.log(container.children);childNodes повертає всі дочірні вузли, зокрема текстові вузли:
console.log(container.childNodes);Наприклад, у такому HTML:
<div class="container">
<p>Перший абзац</p>
<p>Другий абзац</p>
</div>Переноси рядків і відступи між тегами можуть бути представлені текстовими вузлами. Тому кількість елементів у children і кількість вузлів у childNodes може відрізнятися.
Для роботи саме з HTML-елементами зазвичай зручніше використовувати:
children;
firstElementChild;
lastElementChild;
nextElementSibling;
previousElementSibling.
Створимо сторінку зі списком завдань. JavaScript знайде заголовок і список, прочитає їхній вміст та виведе інформацію в консоль.
<!DOCTYPE html>
<html lang="uk">
<head>
<meta charset="UTF-8">
<title>Робота з DOM</title>
</head>
<body>
<main class="page">
<h1 id="page-title">Мої завдання</h1>
<ul class="task-list">
<li class="task">Вивчити DOM</li>
<li class="task">Написати програму</li>
<li class="task">Перевірити результат</li>
</ul>
</main>
<script>
const page = document.querySelector('.page');
const title = document.querySelector('#page-title');
const tasks = document.querySelectorAll('.task');
console.log('Кореневий елемент сторінки:', page);
console.log('Текст заголовка:', title.textContent);
console.log('Кількість завдань:', tasks.length);
tasks.forEach((task, index) => {
console.log(`${index + 1}. ${task.textContent}`);
});
console.log('Батьківський елемент списку:', tasks[0].parentElement);
console.log('Перший елемент списку:', tasks[0]);
console.log('Наступний елемент:', tasks[0].nextElementSibling);
</script>
</body>
</html>У цьому прикладі:
document.querySelector('.page') знаходить основний контейнер.
document.querySelector('#page-title') знаходить заголовок за ідентифікатором.
document.querySelectorAll('.task') знаходить усі завдання.
textContent читає текст елементів.
parentElement дає змогу перейти до батьківського елемента.
nextElementSibling дає змогу перейти до наступного елемента списку.
DOM схожий на HTML, але це не одне й те саме.
HTML — це початковий текст документа. DOM — це об’єктна структура, створена браузером на основі цього тексту.
Наприклад, браузер може автоматично виправити некоректну HTML-структуру під час створення DOM. Також JavaScript може змінити DOM після завантаження сторінки, але це не обов’язково змінить початковий HTML-файл на диску.
Якщо виконати:
document.querySelector('h1').textContent = 'Новий заголовок';заголовок на сторінці зміниться, оскільки змінився DOM.
Переглянути DOM можна за допомогою інструментів розробника браузера:
Відкрийте сторінку.
Натисніть клавішу F12 або відкрийте інструменти розробника через меню браузера.
Перейдіть на вкладку Elements або Інспектор.
Розгорніть елементи html, head і body.
У цьому дереві можна побачити:
вкладеність елементів;
атрибути;
текстовий вміст;
поточний стан DOM після виконання JavaScript.
Важливо: вкладка Elements показує поточний DOM, а не обов’язково точний початковий текст HTML-файлу.
Кожен вузол має властивість nodeType.
Для найпоширеніших типів:
1 — елемент;
3 — текстовий вузол;
9 — документ.
const title = document.querySelector('h1');
console.log(title.nodeType); // 1
console.log(document.nodeType); // 9Також можна перевірити назву вузла:
console.log(title.nodeName); // H1Для HTML-елементів властивість tagName повертає назву тега:
console.log(title.tagName); // H1Якщо JavaScript виконується до того, як потрібний HTML з’явився в документі, querySelector може повернути null.
const title = document.querySelector('h1');
console.log(title.textContent);Якщо елемента h1 ще немає, виникне помилка під час звернення до textContent.
Розміщуйте script після HTML-розмітки:
<body>
<h1>Заголовок</h1>
<script src="script.js"></script>
</body>Або використовуйте атрибут defer:
<script src="script.js" defer></script>querySelector і querySelectorAllquerySelector повертає лише перший відповідний елемент:
const firstTask = document.querySelector('.task');querySelectorAll повертає всі відповідні елементи:
const allTasks = document.querySelectorAll('.task');Для класу в CSS-селекторі використовують крапку:
document.querySelector('.card');Для ідентифікатора використовують символ #:
document.querySelector('#main-card');childNodes, коли потрібні лише елементиchildNodes може містити текстові вузли, створені пробілами та переносами рядків. Якщо потрібно перебрати лише HTML-елементи, використовуйте children.
Завжди враховуйте, що пошук може не знайти елемент:
const button = document.querySelector('.button');
if (button) {
console.log(button.textContent);
}Перевірка особливо важлива для скриптів, які підключаються до кількох сторінок із різною HTML-структурою.
DOM — це об’єктне представлення HTML-документа.
DOM має деревоподібну структуру з батьківськими та дочірніми вузлами.
document представляє всю сторінку.
HTML-елементи є вузлами типу element, а текст усередині них — текстовими вузлами.
querySelector повертає перший елемент, що відповідає CSS-селектору.
querySelectorAll повертає всі відповідні елементи.
parentElement, children та властивості для переходу між сусідніми елементами допомагають переміщатися DOM-деревом.
children містить лише елементи, а childNodes — усі дочірні вузли.
JavaScript може читати DOM і змінювати його під час роботи сторінки.