Понять, что такое DOM

внешний интерфейс JavaScript браузер HTML

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

Как устроены веб-страницы

То, как браузер переходит от исходного HTML-документа к отображению стилизованной и интерактивной страницы в области просмотра, называется «критическим путем рендеринга». Эти шаги можно условно разделить на два этапа. На первом этапе браузер анализирует документ, чтобы определить, что в конечном итоге будет отображаться на странице, а на втором этапе браузер выполняет визуализацию.

Результатом первого этапа является то, что называется «деревом рендеринга». Дерево рендеринга — это представление элементов 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 — это взаимно однозначное сопоставление исходного HTML-документа или того, что вы видите с помощью DevTools. Однако, как я уже говорил, есть отличия. Чтобы полностью понять, что такое DOM, нам нужно взглянуть на то, чем он не является.

DOM не является исходным HTML-документом

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

1. Когда HTML недействителен

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

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

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

В документе отсутствует элемент and, необходимый для корректного HTML. Если мы посмотрим на результирующее DOM-дерево, то увидим, что это было исправлено:

html
    head
    body
        Hello, world!

2. Когда JavaScript изменяет DOM

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

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

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

Вышеприведенное изменит наш DOM, но не наш HTML-документ.

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

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

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

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

Приведенная выше структура DOM будет содержать элементы

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

Однако дерево рендеринга, которое мы видим в окне просмотра, не содержит этого элемента p.

html
    body
        h1
            Hello, world!

DOM не является структурой в DevTools

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

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

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

Вот почему Javascript не имеет прямого доступа к псевдоэлементам, потому что псевдоэлементы не являются частью DOM.

Суммировать

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

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

  1. это всегда действительный HTML
  2. Это структура, которую можно изменить с помощью Javascript.
  3. Он не содержит псевдоэлементов (например, ::after)
  4. Он содержит скрытые элементы (например,дисплей: нет)