JavaScript

Что такое DOM?

Spread the love

Объектная модель документа, или «DOM», является программным интерфейсом доступа к элементам веб-страниц. По сути, это API страницы, позволяющий читать и манипулировать содержимым, структурой и стилями страницы. Давайте разберемся как это устроено и как это работает.

Как строится веб-страница?

Процесс преобразования исходного HTML-документа в отображаемую стилизованную и интерактивную страницу, называется “Critical Rendering Path”(«Критическим путем рендеринга»). Хотя этот процесс можно разбить на несколько этапов, как я описал это в статье «Понимание критического пути рендеринга», эти этапы можно условно сгруппировать в два этапа. В первом браузер анализирует документ, чтобы определить, что в конечном итоге будет отображаться на странице, а во второй браузер выполняет рендеринг.

Результатом первого этапа является то, что называется “render tree”(«дерево рендеринга»). Дерево рендеринга — это представление элементов HTML, которые будут отображаться на странице, и связанных с ними стилей. Чтобы построить это дерево, браузеру нужны две вещи:

  1. CSSOM, представление стилей, связанных с элементами
  2. DOM, представление элементов

Из чего состоит DOM?

DOM — это объектное представление исходного HTML-документа. Он имеет некоторые различия, как мы увидим ниже, но по сути это попытка преобразовать структуру и содержание документа HTML в объектную модель, которая может использоваться различными программами.

Структура объектов DOM представлена тем, что называется «деревом узлов». Оно так называется, потому что его можно рассматривать как дерево с одним родительским элементом, который разветвляется на несколько дочерних ветвей, каждая из которых может иметь листья. В этом случае родительский «элемент» — это корневой элемент , дочерние «ветви» — это вложенные элементы, а «листья» — это содержимое внутри элементов.

Давайте рассмотрим этот HTML-документ в качестве примера:

<!doctype html>
<html lang="en">
 <head>
   <title>My first web page</title>
  </head>
 <body>
    <h1>Hello, world!</h1>
    <p>How are you?</p>
  </body>
</html>

Этот документ может быть представлен в виде следующего дерева узлов:

  • html
    • head
      • title
        • My first web page
    • body
      • h1
        • Hello, world!
      • p
        • How are you?

Чем DOM не является

В приведенном выше примере кажется, что DOM является отображением 1: 1 исходного HTML-документа. Однако, как я уже говорил, есть различия. Чтобы полностью понять, что такое DOM, нам нужно взглянуть на то, чем он не является.

DOM не является копией исходного HTML

Хотя DOM создан из HTML-документа, он не всегда точно такой же. Есть два случая, в которых DOM может отличаться от исходного HTML.

1. Когда HTML содержит ошибки разметки

DOM — это интерфейс доступа к действительных (то есть уже отображаемым) элементам документа HTML. В процессе создания DOM, браузер сам может исправить некоторые ошибки в коде HTML.

Рассмотрим в качестве примера этот HTML-документ:

<!doctype html>
<html>
Hello, world!
</html>

В документе отсутствуют элементы  <head>  и  <body> , что является обязательным требованием для HTML. Но если мы посмотрим на получившееся дерево DOM, то увидим, что это было исправлено:

  • html
    • head
    • body
      • Hello, world!

2. Когда DOM модифицируется кодом Javascript

Помимо того, что DOM является интерфейсом для просмотра содержимого документа HTML, он сам также может быть изменен.

Мы можем, например, создать дополнительные узлы для DOM, используя Javascript.

var newParagraph = document.createElement("p");
var paragraphContent = document.createTextNode("I'm new!");
newParagraph.appendChild(paragraphContent);
document.body.appendChild(newParagraph);

Этот код изменит DOM, но изменения не отобразятся в документе HTML .

DOM — это не то, что вы видите в браузере (то есть, дерево рендеринга)

В окне просмотра браузера вы видите дерево рендеринга, которое, как я уже говорил, является комбинацией DOM и CSSOM. Чем отличается DOM от дерева рендеринга, так это то, что последнее состоит только из того, что в конечном итоге будет отображено на экране.

Поскольку дерево рендеринга имеет отношение только к тому, что отображается, оно исключает элементы, которые визуально скрыты. Например, элементы, у которых есть стили с display: none.

<!doctype html>
<html lang="en">
  <head></head>
  <body>
    <h1>Hello, world!</h1>
    <p style="display: none;">How are you?</p>
  </body>
</html>

DOM будет включать элемент <p>:

  • html
    • head
    • body
      • h1
        • Hello, world!
      • p
        • How are you?

Однако дерево рендеринга и, следовательно, то, что видно в окне просмотра, не будет включено в этот элемент.

  • html
    • body
      • h1
        • Hello, world!

DOM — это не то, что отображается в DevTools

Это различие немного меньше, потому что инспектор элементов DevTools обеспечивает самое близкое приближение к DOM, которое мы имеем в браузере. Однако инспектор DevTools содержит дополнительную информацию, которой нет в DOM.

Лучший пример этого — псевдоэлементы CSS. Псевдоэлементы, созданные с использованием селекторов ::before и ::after, являются частью CSSOM и дерева рендеринга, но технически не являются частью DOM. Это связано с тем, что DOM создается только из исходного HTML-документа, не включая стили, примененные к элементу.

Несмотря на то, что псевдоэлементы не являются частью DOM, они есть в нашем инспекторе элементов devtools.

Резюме

DOM — это интерфейс к HTML-документу. Он используется браузерами как первый шаг к определению того, что визуализировать в окне просмотра, и кодом Javascript для изменения содержимого, структуры или стиля страницы.

Хотя DOM похож на другие формы исходного документа HTML, он отличается по ряду причин:

  • Это всегда верный (валидный) HTML код
  • Это модель, которая может быть изменена с помощью Javascript
  • В него не входят псевдоэлементы (такие как ::after)
  • В него входят скрытые элементы (такие как display: none)

Оригинальная статья

Была ли вам полезна эта статья?
[15 / 4.9]

Spread the love
Editorial Team

View Comments

  • У вас ошибка в статье:
    В него не входят скрытые элементы (такие как display: none)

    Они как раз-таки входят, о чем пишется в оригинале.
    Прошу исправить)

    • Да вы правы. Спасибо за комментарий.

Recent Posts

Vue 3.4 Новая механика v-model компонента

Краткий перевод: https://vuejs.org/guide/components/v-model.html Основное использование​ v-model используется для реализации двусторонней привязки в компоненте. Начиная с Vue…

11 месяцев ago

Анонс Vue 3.4

Сегодня мы рады объявить о выпуске Vue 3.4 «🏀 Slam Dunk»! Этот выпуск включает в…

11 месяцев ago

Как принудительно пере-отобразить (re-render) компонент Vue

Vue.js — это универсальный и адаптируемый фреймворк. Благодаря своей отличительной архитектуре и системе реактивности Vue…

2 года ago

Проблемы с установкой сертификата на nginix

Недавно, у меня истек сертификат и пришлось заказывать новый и затем устанавливать на хостинг с…

2 года ago

Введение в JavaScript Temporal API

Каким бы ни было ваше мнение о JavaScript, но всем известно, что работа с датами…

2 года ago

Когда и как выбирать между медиа запросами и контейнерными запросами

Все, кто следит за последними событиями в мире адаптивного дизайна, согласятся, что введение контейнерных запросов…

2 года ago