DOM

Материал из llmdocs — справочник разработчика
DOM
Полное название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, строит DOM, применяет к нему стили CSS и отрисовывает результат; JavaScript через 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. Для разметки

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

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

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

// поиск по 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-атакам.

События

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

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

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

Фреймворки решают задачу по-разному: React и Vue сравнивают виртуальный DOM (лёгкую копию дерева) и применяют минимальный набор изменений; Svelte и Solid генерируют точечные обновления при компиляции; генераторы статических сайтов отдают готовый HTML и обходятся почти без работы с DOM.

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

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

Доступность

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

См. также

Источники

  1. WHATWG — DOM Living Standard
  2. MDN — Introduction to the DOM
  3. MDN — Event bubbling
  4. MDN — Using shadow DOM
  5. web.dev — Avoid large, complex layouts and layout thrashing
  6. W3C — Document Object Model (DOM) Level 1 Specification