12 червня 2022 р.

DOM дерево

Теги – основа HTML-документа це .

Відповідно до об’єктної моделі документа (DOM), кожен HTML-тег є об’єктом. Вкладені теги – це “діти” всередині батьківського елементу. Текст всередині тегу також є об’єктом.

Всі ці об’єкти доступні за допомогою JavaScript, і ми можемо використовувати їх, щоб змінити сторінку.

Наприклад, document.body це об’єкт, що представляє тег <body>.

Запуск цього коду зробить <body> червоним протягом 3 секунд:

document.body.style.background = 'red'; // зробити фон червоним

setTimeout(() => document.body.style.background = '', 3000); // повернути назад

Тут ми використовували style.background, щоб змінити фоновий колір document.body, але тут є багато інших властивостей, таких як.

  • innerHTML – вміст HTML вузла.
  • offsetWidth – ширина вузла (у пікселях)
  • …і так далі.

Незабаром ми дізнаємося більше способів маніпулювати домом, але спочатку потрібно знати його структуру.

Приклад DOM

Почнемо з наступного простого документа:

<!DOCTYPE HTML>
<html>
<head>
  <title>Про лосів</title>
</head>
<body>
  Правда про лосів.
</body>
</html>

DOM представляє HTML як структуру дерева тегів. Ось як це виглядає:

На зображенні вище, ви можете натиснути на вузли-елементи, а їхні діти будуть відкриватися і закриватися.

Кожен вузол дерева є об’єктом.

Теги є вузлами-елементами (або просто елементами), вони утворюють структуру дерева: <html> знаходиться в корені, <head> <body> – це його дочірні вузли тощо.

Текст всередині елементів утворює текстові вузли, позначені як #text. Текстовий вузол містить лише рядок. У нього може не буди нащадків і він завжди є листом дерева.

Наприклад, тег <title> має текст "Про лосів".

Зверніть увагу на спеціальні символи в текстових вузлах:

  • новий рядок: (в JavaScript відомий як \n)
  • пробіл:

Пробіли та нові рядки є абсолютно діючими символами, як букви та цифри. Вони утворюють текстові вузли і стають частиною DOM. Отже, наприклад, наведений вище тег <head> містить деякі пробіли перед <title>, і цей текст стає #text вузлом (він містить лише символ нового рядку та деякілька пробілів).

Є лише два винятки з цього правила:

  1. Пробіли та нові лінії до <head> ігноруються з історичних причин.
  2. Якщо ми щось помістимо після <body>, то це цось автоматично переміщується всередині body, в кінці, оскільки специфікація HTML вимагає, що весь вміст повинен бути всередині <body>. Отже, після <body> не може бути пробілів.

В інших випадках все просто – якщо є пробіли (так само, як будь-який символ) у документі, то вони стають текстовими вузлами в DOM, і якщо ми видалимо ці пробіли, то текстових вузлів там не буде.

Тут немає текстових вузлів з пробілами:

<!DOCTYPE HTML>
<html><head><title>Про оленів</title></head><body>Правда про оленів.</body></html>
Пробіли у рядку на початку/в кінці і ті вузли, що містять тільки пробіли, як правило, приховані в інструментах розробки

Інструменти браузера (будуть розглянуті скоро), що працюють з DOM, як правило, не показують пробіли на початку/кінці тексту та порожні тексти (переноси рядків) між тегами.

Інструменти розробника таким чином зберігають екранний простір.

На подальших рисунках DOM ми іноді опускаємо їх, коли вони не мають значення. Такі пробіли зазвичай не впливають на те, як відображається документ.

Автокорекція

Якщо браузер зтикається з невалідним HTML, він автоматично виправляє його при створенні DOM.

Наприклад, верхній тег завжди <html>. Навіть якщо він не існує в документі, він буде існувати в DOM, тому що браузер створить його. Те ж саме стосується <body>.

Як приклад, якщо файл HTML містить єдине слово "Привіт", браузер оберне його в <html> і <body>, та додасть необхідний <head>, а DOM буде виглядати наступним чином:

Під час створення DOM, браузери автоматично обробляють помилки у документі, закривають теги тощо.

Документ з відкритими тегами:

<p>Привіт
<li>Мама
<li>і
<li>Тато

…стане нормальним DOM, оскільки браузер читає теги та відновлює відсутні частини:

Таблиці завжди мають <tbody>

Цікавий “особливий випадок” – це таблиці. Згідно DOM специфікації вони повинні мати тег <tbody>, але текст HTML може це пропустити. Тоді браузер створює <tbody> у DOM автоматично.

Наприклад, HTML:

<table id="table"><tr><td>1</td></tr></table>

DOM-структура:

Розумієте? Тег <tbody> з’явився з нізвідки. Ми повинні мати це на увазі під час роботи з таблицями, щоб уникати сюрпризів.

Інші типи вузлів

Окрім елементів та текстових вузлів є деякі інщі типи вузлів.

Наприклад, коментарі:

<!DOCTYPE HTML>
<html>
<body>
  Правда про оленів.
  <ol>
    <li>Олень -- це розумний</li>
    <!-- comment -->
    <li>...та хитрий звір!</li>
  </ol>
</body>
</html>

Тут ми бачимо новий тип вузла дерева – вузол-коментар, позначений як #comment, між двома текстовими вузлами.

Ми могли подумати – чому коментар додається до DOM? Це не впливає на візуальне уявлення. Але є правило – якщо щось є в HTML, то воно також повинно бути в DOM дереві.

Все в HTML, навіть коментарі, стає частиною DOM.

Навіть директива <!DOCTYPE...> на самому початку HTML також є вузлом DOM. Вона є DOM дереві прямо перед <html>. Мало хто знає про це. Ми не збираємося звертатися до цього вузла, ми навіть не малюємо його на діаграмах, але він там є.

Об’єкт document, який представляє весь документ, формально, також є вузлом DOM.

Існує 12 типів вузлів. На практиці ми зазвичай працюємо з 4-ма з них:

  1. document – “пункт входу” в DOM.
  2. вузли-елементи – HTML-теги, будівельні блоки дерев.
  3. текстові вузли – містять текст.
  4. коментарі – іноді ми можемо записати туди інформацію, вона не буде показана, але JS може читати її з DOM.

Поекспериментуйте самі

Щоб побачити структуру DOM у режимі реального часу, спробуйте Live Dom Viewer. Просто введіть документ, і внизу відразу з’явиться його DOM.

Іншим способом вивчення DOM є використання інструментів розробника браузера. Взагалі, це те, що ми використовуємо при розробці.

Для цього відкрийте веб-сторінку elk.html, увімкніть інструменти розробника в браузері та перейдіть на вкладку “Elements”.

Це повинно виглядати так:

Ви можете побачити DOM, натиснути на елементи, переглянути їхні деталі і так далі.

Зверніть увагу, що структура DOM в інструментах розробника спрощується. Текстові вузли показані так само, як текст. І взагалі немає “порожніх” (тільки пробіли) текстових вузлів. Це добре, тому що більшу частину часу ми зацікавлені в вузлах-елементах.

Якщо натиснути кнопку у лівому верхньому куті, то можна буде вибрати вузол з веб-сторінки за допомогою миші (або інших пристроїв покажчика) і “проінспектувати” його (прокрутити до нього на вкладці “Elements”). Це чудово працює, коли у нас є величезна HTML-сторінка (і відповідний величезний дом) і хотілося б побачити місце конкретного елемента в ньому.

Інший спосіб зробити це – просто натиснувши праву клавіщу миші на веб-сторінці та вибирати “Inspect” у контекстному меню.

У правій частині інструментів є наступні підвкладки:

  • Styles – ми можемо бачити CSS правила, які застосовано до поточного елемента, включаючи вбудовані правила (показані сірим). Майже все можна відредагувати на місці, включаючи розміри/марджини/паддінги внизу вікна.
  • Computed – для перегляду CSS, що застосовується до елемента за властивістю: для кожної властивості ми можемо побачити правило, яке це дає (включаючи наслідування CSS та ін.).
  • Event Listeners – щоб побачити слухачів подій, що прикріплені до елементів DOM (ми розглянемо їх у наступній частині підручника).
  • …і так далі.

Найкращий спосіб вивчити все це – поекспериментувати. Більшість значень можна редагувати на місці.

Взаємодія з консоллю

Коли ми працюємо з DOM, ми також можемо застосувати до нього JavaScript. Наприклад, отримайти вузол і запустити якийсь код, щоб змінити його так, щоб побачити результат. Ось декілька порад, щоб переміщатися між вкладкою “Elements” та консоллю.

Для початку:

  1. Виберіть першу <li> на вкладці елементів.
  2. Натисніть Esc – це відкриє консоль прямо під вкладкою “Елементи”.

Тепер останній вибраний елемент доступний як $0, раніше вибраний – $1, тощо.

Ми можемо запустити команди на них. Наприклад, $0.style.background = 'red' робить вибраний список елементів червоним, наприклад:

Ось як отримати вузол з елементів у консолі.

Також існує зворотній шлях. Якщо є змінна, що посилається на вузол DOM, то ми можемо використовувати команду inspect(node) у консолі, щоб побачити його в панелі елементів.

Або ми можемо просто вивести вузол DOM в консолі та дослідити його “на місці”, як і document.body нижче:

Звичайно, це використовується з метою відлагодження. З наступної глави ми будемо отримувати доступ та змінювати DOM за допомогою JavaScript.

Інструменти розробника браузера – є дуже корисними у розробці: ми можемо досліджувати DOM, випробовувати різні речі і дивитися, що йде не так.

Підсумки

HTML/XML документ представляється всередині браузера, як дерево DOM.

  • Теги стають вузлами-елементами і утворюють структуру.
  • Текст стає текстовими вузлами.
  • …і т.д., все, що є в HTML, представлено в DOM, навіть коментарі.

Ми можемо використовувати інструменти розробника, щоб перевіряти DOM та змінювати його вручну.

Тут для початку ми охопили основи та дії, які найбільш часто використовуються. Існує велика документація про інструменти розробника Chrome на https://developers.google.com/web/tools/chrome-devtools. Найкращий спосіб дізнатися більше про інструменти розробника – це відкрити їх та ознайомитися з ними: більшість можливостей очевидні. Пізніше, коли ви загалом розберетеся з ними, читайте документацію, щоб дослідити решту функціоналу.

Вузли DOM мають властивості та методи, які дозволяють нам переміщуватися між ними, змінювати їх, переміщуватися по сторінці та багато іншого. Ми розберемо їх у наступних розділах.

Навчальна карта

Коментарі

прочитайте це, перш ніж коментувати…
  • Якщо у вас є пропозиції, щодо покращення підручника, будь ласка, створіть обговорення на GitHub або одразу створіть запит на злиття зі змінами.
  • Якщо ви не можете зрозуміти щось у статті, спробуйте покращити її, будь ласка.
  • Щоб вставити код, використовуйте тег <code>, для кількох рядків – обгорніть їх тегом <pre>, для понад 10 рядків – використовуйте пісочницю (plnkr, jsbin, codepen…)