# DOM

> Объектная модель документа — древовидное представление HTML-страницы в браузере и программный интерфейс, через который JavaScript читает и изменяет её.

Источник: https://llmdocs.ru/wiki/dom/ · обновлено 2026-11-09 · лицензия CC BY-SA 4.0

- **Полное название**: Document Object Model
- **Первая спецификация**: DOM Level 1 (W3C, октябрь 1998)
- **Текущий стандарт**: DOM Living Standard (WHATWG)
- **Языковая привязка**: JavaScript (Web IDL)
- **Основные интерфейсы**: Node, Element, Document, Event, EventTarget
- **Связанные стандарты**: HTML, CSSOM, Shadow DOM, Custom Elements
**DOM** (англ. *Document Object Model* — объектная модель документа) — представление веб-страницы в памяти браузера в виде дерева объектов и стандартный программный интерфейс к этому дереву. Браузер разбирает [HTML](https://llmdocs.ru/wiki/html.md), строит DOM, применяет к нему стили [CSS](https://llmdocs.ru/wiki/css.md) и отрисовывает результат; [JavaScript](https://llmdocs.ru/wiki/javascript.md) через DOM находит элементы, меняет их содержимое и атрибуты, добавляет и удаляет узлы и реагирует на действия пользователя. Изменения в DOM сразу отражаются на экране.[2]

## История

В эпоху «войны браузеров» конца 1990-х Netscape и Internet Explorer предлагали несовместимые способы доступа к странице из скриптов (`document.layers` против `document.all`) — сейчас их называют «DOM уровня 0». Консорциум W3C выпустил DOM Level 1 в 1998 году, затем Level 2 (события, стили, 2000) и Level 3 (2004).[6] Различия реализаций ещё долго сохранялись, что во многом объясняет популярность jQuery в 2006–2015 годах. Сейчас DOM развивается как «живой стандарт» в WHATWG, вместе со стандартом HTML.[1]

## Дерево узлов

Документ — это дерево **узлов** (`Node`). Основные типы: `Document` (корень), `Element` (теги), `Text` (текст), `Comment`. Для разметки

```html
<ul id="menu">
  <li class="active">Главная</li>
  <li>Статьи</li>
</ul>
```

DOM будет содержать элемент `ul` с двумя дочерними элементами `li`, у каждого — текстовый узел (а между ними — текстовые узлы с пробелами и переводами строк). Браузер исправляет ошибки разметки при разборе, поэтому DOM может отличаться от исходного HTML: например, в таблицу автоматически добавляется `tbody`.

## Основные операции

```js
// поиск по CSS-селекторам
const menu = document.querySelector("#menu");
const items = menu.querySelectorAll("li");

// чтение и изменение
items[1].textContent = "Вики";
items[0].classList.remove("active");
menu.setAttribute("aria-label", "Главное меню");

// создание и вставка
const li = document.createElement("li");
li.textContent = "О проекте";
menu.append(li);

// события
menu.addEventListener("click", (e) => {
  const item = e.target.closest("li");
  if (item) console.log("клик по", item.textContent);
});
```

Свойство `textContent` безопасно для пользовательских данных; присваивание строки в `innerHTML` разбирает её как HTML и при неосторожном использовании открывает дорогу [XSS-атакам](https://llmdocs.ru/wiki/xss.md).

## События

Событие (клик, ввод, отправка формы) проходит три фазы: **погружение** от `document` к целевому элементу, **цель** и **всплытие** обратно вверх по дереву.[3] Всплытие позволяет применять **делегирование**: один обработчик на родителе (как в примере выше) обслуживает всех потомков, включая добавленных позже. Метод `preventDefault()` отменяет действие браузера по умолчанию, `stopPropagation()` — дальнейшее распространение события.

## Производительность

Изменение DOM может заставить браузер пересчитать стили, раскладку (layout, reflow) и перерисовать страницу. Самая частая ошибка — чередование записи и чтения геометрии (`offsetHeight`, `getBoundingClientRect`) в цикле: каждое чтение вынуждает синхронный пересчёт раскладки (layout thrashing).[5] Рекомендуется группировать изменения, использовать `DocumentFragment`, анимировать `transform` и `opacity`.

Фреймворки решают задачу по-разному: React и Vue сравнивают **виртуальный DOM** (лёгкую копию дерева) и применяют минимальный набор изменений; Svelte и Solid генерируют точечные обновления при компиляции; генераторы [статических сайтов](https://llmdocs.ru/wiki/static-site-generators.md) отдают готовый HTML и обходятся почти без работы с DOM.

## Shadow DOM и веб-компоненты

**Shadow DOM** позволяет прикрепить к элементу скрытое поддерево с изолированными стилями и разметкой — так устроены встроенные элементы вроде `<video>` и пользовательские **веб-компоненты** (Custom Elements).[4] Стили страницы не проникают внутрь теневого дерева, а стили компонента не утекают наружу.

## Доступность

Помимо DOM браузер строит **дерево доступности**, которое читают экранные читалки. Оно выводится из DOM: семантических тегов, атрибутов `aria-*`, порядка узлов. Поэтому семантика разметки важнее визуального вида — см. [Веб-доступность (a11y)](https://llmdocs.ru/wiki/accessibility.md).

## См. также

- [HTML](https://llmdocs.ru/wiki/html.md)
- [JavaScript](https://llmdocs.ru/wiki/javascript.md)
- [CSS](https://llmdocs.ru/wiki/css.md)
- [Flexbox и Grid](https://llmdocs.ru/wiki/flexbox-grid.md)
- [Веб-доступность (a11y)](https://llmdocs.ru/wiki/accessibility.md)

## Источники

1. [WHATWG — DOM Living Standard](https://dom.spec.whatwg.org/)
2. [MDN — Introduction to the DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction)
3. [MDN — Event bubbling](https://developer.mozilla.org/en-US/docs/Learn_web_development/Core/Scripting/Event_bubbling)
4. [MDN — Using shadow DOM](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_shadow_DOM)
5. [web.dev — Avoid large, complex layouts and layout thrashing](https://web.dev/articles/avoid-large-complex-layouts-and-layout-thrashing)
6. [W3C — Document Object Model (DOM) Level 1 Specification](https://www.w3.org/TR/REC-DOM-Level-1/)
