DOM
DOM (от англ. Document Object Model — объектная модель документа) — это программный интерфейс (API), предоставляющий браузеру и скриптовым языкам (прежде всего JavaScript) структурированное представление HTML- или XML-документа в виде дерева объектов (узлов), а также набор методов для доступа к этим объектам, их изменения, добавления и удаления. DOM является кросс-платформенным и языконезависимым стандартом, определённым Консорциумом Всемирной паутины (W3C).
История и развитие
Истоки и первые реализации
До появления единого стандарта DOM каждый браузер реализовывал собственную модель документа, что приводило к серьёзным проблемам совместимости. В середине 1990-х годов, с ростом популярности JavaScript и технологии Dynamic HTML (DHTML), разработчики столкнулись с тем, что один и тот же код мог работать в Internet Explorer, но не в Netscape Navigator, и наоборот. Для решения этой проблемы W3C начал работу по стандартизации.
Уровни DOM (DOM Levels)
Стандарт DOM развивался поэтапно:
- DOM Level 0 (1996—1997): Неофициальное обозначение для ранних, нестандартизированных моделей, реализованных в браузерах Netscape Navigator 2.0/3.0 и Internet Explorer 3.0/4.0. Включал базовые объекты, такие как
document.images,document.formsиdocument.layers(только в Netscape). - DOM Level 1 (1998): Первая официальная рекомендация W3C. Определил основную структуру DOM как дерево узлов (
Node,Element,Attr,Text) и базовые методы для навигации по дереву (childNodes,parentNode) и манипуляции с ним (appendChild,removeChild). Устранил разрыв между моделями браузеров, но не включал поддержку событий и стилей. - DOM Level 2 (2000): Значительно расширил функциональность. Ввёл:
- Модель событий (DOM Events):
addEventListener,removeEventListener, объектEventс фазами всплытия и перехвата. - Поддержку CSS (CSS Object Model): доступ к таблицам стилей и правилам через объект
style. - Работу с диапазонами (DOM Range): выделение и манипуляция фрагментами документа.
- Поддержку пространств имён XML.
- DOM Level 3 (2004): Уточнил и расширил предыдущие уровни. Ввёл:
- Единый интерфейс загрузки и сохранения (DOM Load and Save).
- Поддержку XPath (DOM XPath).
- Улучшенную работу с текстовыми узлами и сущностями.
- Метод
compareDocumentPositionдля точного сравнения положения узлов. - DOM Living Standard (с 2015): Начиная с 2015 года, W3C и WHATWG (Web Hypertext Application Technology Working Group) перешли к модели «живого стандарта». DOM больше не выпускается как фиксированные версии (Level 4 не был завершён). Вместо этого спецификация постоянно обновляется, добавляя новые возможности (например,
Intersection Observer,Mutation Observer,Custom Elements). Современные браузеры следуют именно этой модели.
Архитектура и структура
Древовидная модель
DOM представляет документ как иерархическое дерево узлов. Каждый элемент HTML-разметки, атрибут, текстовый фрагмент или комментарий является отдельным узлом. Корнем дерева является объект Document. От него отходят ветви — дочерние узлы, которые, в свою очередь, могут иметь свои дочерние узлы.
Пример HTML-кода: ``html <!DOCTYPE html> <html> <head> <title>Пример</title> </head> <body> <p>Текст абзаца</p> </body> </html> `` В DOM это превращается в дерево, где:
Document(корень)DocumentType(<!DOCTYPE html>)Element htmlElement headElement titleText(«Пример»)Element bodyElement pText(«Текст абзаца»)
Типы узлов
Спецификация DOM определяет несколько типов узлов, каждый из которых имеет свой числовой код (nodeType):
| Тип узла | nodeType | Описание | Пример |
|---|---|---|---|
Element | 1 | Представляет HTML- или XML-элемент. Самый распространённый тип. | <div>, <a>, <span> |
Attr | 2 | Представляет атрибут элемента. В современном DOM редко используется напрямую, атрибуты доступны через методы элемента. | class="main", id="header" |
Text | 3 | Содержит текстовое содержимое элемента или атрибута. | «Пример», «Текст абзаца» |
Comment | 8 | Представляет комментарий в разметке. | <!-- это комментарий --> |
Document | 9 | Корневой узел, представляющий весь документ. | document |
DocumentType | 10 | Содержит информацию о типе документа (DTD). | <!DOCTYPE html> |
DocumentFragment | 11 | «Лёгкий» контейнер для временного хранения фрагментов документа. Не отображается в DOM. | — |
Навигация по дереву
Для перемещения между узлами используются свойства навигации:
parentNode— родительский узел.childNodes— коллекция (NodeList) всех дочерних узлов, включая текстовые и комментарии.firstChild/lastChild— первый и последний дочерние узлы.nextSibling/previousSibling— следующий и предыдущий соседние узлы.
Для работы с элементами (игнорируя текстовые узлы) существуют аналогичные свойства: parentElement, children, firstElementChild, lastElementChild, nextElementSibling, previousElementSibling.
Основные интерфейсы и методы
Доступ к элементам
Для поиска узлов в дереве DOM предоставляются методы объекта document:
getElementById(id)— возвращает элемент с указанным идентификатором (самый быстрый метод).getElementsByClassName(name)— возвращает живую коллекцию элементов с указанным классом.getElementsByTagName(tag)— возвращает живую коллекцию элементов с указанным тегом.querySelector(selector)— возвращает первый элемент, соответствующий CSS-селектору.querySelectorAll(selector)— возвращает статическую коллекцию (NodeList) всех элементов, соответствующих CSS-селектору.
Манипуляция содержимым и атрибутами
innerHTML— свойство, позволяющее получить или установить HTML-содержимое элемента (включая дочерние элементы).textContent— свойство, возвращающее или задающее текстовое содержимое элемента без HTML-тегов.outerHTML— свойство, возвращающее или заменяющее сам элемент вместе с его содержимым.setAttribute(name, value)— устанавливает значение атрибута.getAttribute(name)— возвращает значение атрибута.removeAttribute(name)— удаляет атрибут.classList— объект, предоставляющий методы для управления классами:add(),remove(),toggle(),contains().
Создание и удаление узлов
document.createElement(tag)— создаёт новый элемент.document.createTextNode(text)— создаёт текстовый узел.parentNode.appendChild(child)— добавляет дочерний узел в конец списка.parentNode.insertBefore(newNode, referenceNode)— вставляет узел перед указанным.parentNode.removeChild(child)— удаляет дочерний узел.element.cloneNode(deep)— создаёт копию узла (еслиdeep = true, копируются все потомки).
Работа со стилями
element.style— объект, представляющий встроенные стили элемента. Позволяет читать и устанавливать отдельные CSS-свойства (например,element.style.color = 'red'). Имена свойств записываются в camelCase (например,backgroundColorвместоbackground-color).window.getComputedStyle(element)— метод, возвращающий объект со всеми вычисленными (актуальными) стилями элемента, включая те, что заданы через CSS-классы.
Модель событий (DOM Events)
DOM предоставляет механизм для обработки действий пользователя или изменений состояния документа (клики, нажатия клавиш, загрузка страницы, отправка формы).
Фазы события
Согласно DOM Level 2, стандартное событие проходит три фазы:
- Фаза перехвата (capturing phase): Событие движется от корня (
document) к целевому элементу. - Фаза цели (target phase): Событие достигает целевого элемента.
- Фаза всплытия (bubbling phase): Событие движется обратно от целевого элемента к корню. Большинство событий (например,
click) всплывают.
Добавление и удаление обработчиков
element.addEventListener(event, handler, options)— назначает функцию-обработчик на событие. Параметрoptionsможет содержать флаги:capture(слушать на фазе перехвата),once(выполнить один раз),passive(указывает, что обработчик не вызоветpreventDefault()).element.removeEventListener(event, handler)— удаляет ранее назначенный обработчик (требуется передача той же самой функции).event.preventDefault()— отменяет стандартное действие браузера (например, переход по ссылке).event.stopPropagation()— прекращает дальнейшее распространение события (не даёт ему всплыть или перехватиться).
Производительность и критика
Проблемы производительности
DOM — это интерфейс, а не само содержимое. Каждый раз, когда скрипт обращается к DOM, происходит «переход» между средой выполнения JavaScript (движок V8, SpiderMonkey и т.д.) и средой рендеринга браузера. Частые и неоптимальные обращения (например, изменение стилей в цикле) могут приводить к перекомпоновке (reflow) и перерисовке (repaint) страницы, что замедляет работу.
Виртуальный DOM (Virtual DOM)
Для решения проблем производительности в некоторых фреймворках (React, Vue.js) используется концепция виртуального DOM. Вместо прямого изменения реального DOM, изменения сначала вносятся в лёгкую копию (виртуальное дерево), а затем специальный алгоритм (diffing) вычисляет минимальный набор изменений и применяет их к реальному DOM за одну операцию. Это значительно снижает количество дорогостоящих перестроек.
Критика
- Избыточность для простых задач: Для статических страниц или простой анимации полный DOM API может быть излишне громоздким.
- Сложность отладки: Асинхронные изменения DOM и сложные цепочки событий могут затруднять отладку.
- Безопасность: Использование
innerHTMLс непроверенными данными может привести к XSS-атакам (межсайтовый скриптинг). Рекомендуется использоватьtextContentили методы создания узлов.
Применение
DOM является основой для всех современных веб-приложений. Он используется для:
- Динамического обновления содержимого страницы без перезагрузки (AJAX, SPA).
- Создания интерактивных интерфейсов (меню, слайдеры, формы).
- Валидации данных на стороне клиента.
- Реализации drag-and-drop (перетаскивание объектов).
- Создания игр и визуализаций в браузере.
- Работы с SVG-графикой.
Источники
- Спецификация DOM Living Standard (WHATWG).
- Рекомендации W3C: DOM Level 1, Level 2, Level 3.
- Документация Mozilla Developer Network (MDN) по DOM.
- Учебник «Современный учебник JavaScript» (learn.javascript.ru), раздел «Document Object Model».
- Книга Дэвида Флэнагана «JavaScript. Подробное руководство» (7-е издание).
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →