Что такое dom в 1с
Данная публикация предваряет ряд статей об альтернативных способах работы с XML. "Альтернативных", потому что как правило работа с XML в 1С ограничивается разбором xml при помощи последовательного чтения - построчного разбора текстового содержимого. А ведь есть еще и другие способы.
Например, использование языка запросов к XML xPath или шаблонов трансформации XSL. Об этих вариантах будет рассказано в следующих статьях. Но все они опираются на базовое представление документов XML в виде DOM. О том, что такое DOM (document object model или объектная модель документа) и пойдет речь в публикации.
DOM базируется на представлении документа любой структуры в виде дерева узлов, каждый узел (нода) которого представляет собой элемент, атрибут элемента, текстовое значение элемента и т.п.. Связь между узлами построена по принципу "родитель - подчиненные". У корня документа (дерева DOM) родителя нет. У тупикового элемента нет подчиненного (такие элементы абстрактно называются листьями дерева). Таким образом модель DOM может создаваться не только для XML, но фактически для любого структурированного документа (HTML, XHTML). Так, например, браузер пользователя, получая HTML код веб-страницы из интернета, строит дерево DOM этой страницы в оперативной памяти компьютера пользователя.
Модель DOM открывает широкие возможности по манипуляции данными документа. Можно создавать новые узлы, вставлять их на разных уровнях дерева, копировать узлы, удалять узлы, искать узлы по разным параметрам и многое другое.
Модель DOM документа XML наглядно представлена на рисунке ниже.
Любой современный язык программирования имеет в своем составе средства (парсеры) для работы с таким деревом. Получая на вход строковое содержимое XML-парсер выстраивает в оперативной памяти дерево узлов и выполняет манипуляции с данными дерева. Преимущество такого подхода перед построчным разбором очевидно: одним запросом к дереву можно выбрать необходимы данные, не перебирая построчно весь документ, ведь в оперативной памяти находится полное представление элементов со всеми взимосвязями.
В платформе 1С модель DOM представлена специальным объектом ДокументDOM, который в свою очередь строится при помощи объекта ПостроительDOM и его метода Прочитать. На вход этому методу, как правило, подается либо объект ЧтениеXML, либо ЧтениеHTML, при помощи которых осуществляется непосредственное считывание из файлов или загрузка из строки текстового содержимого XML или HTML. Ну и далее есть ряд конструкций, позволяющих извлекать данные из объектоной модели прочитанного документа.
Из всех вариантов самым интересным с моей точки зрения является вариант №1 с использованием метода ВычислитьВыражениеXPath. Ему будет посвящена следующая статья.
Плюсы построчного разбора: потребность в ресурсах меньше. Минусы: долго по времени, чтобы получить данные нужно построчно прочитать весь файл, сложность программного кода при разборе XML-документов со сложной структурой.
Преимущество выборки через DOM: скорость выборки данных, простота программного кода. Минусы: требовательность к ресурсам, на построение и запросы к DOM расходуется оперативная память и процессорные мощности.
Браузер, когда запрашивает страницу и получает в ответе от сервера её исходный HTML-код, должен сначала его разобрать. В процессе анализа и разбора HTML-кода браузер строит на основе него DOM-дерево .
После выполнения этого действия и ряда других браузер приступает к отрисовке страницы. В этом процессе он, конечно, уже использует созданное им DOM-дерево , а не исходный HTML-код.
DOM – это объектная модель документа, которую браузер создаёт в памяти компьютера на основании HTML-кода, полученного им от сервера.
Если сказать по-простому, то HTML-код – это текст страницы, а DOM – это набор связанных объектов, созданных браузером при парсинге её текста.
В Chrome исходный код страницы, который получает браузер, можно посмотреть во вкладке «Source» на панели «Инструменты веб-разработчика».
В Chrome инструмента, с помощью которого можно было бы посмотреть созданное им DOM-дерево нет. Но есть представление этого DOM-дерева в виде HTML-кода, оно доступно на вкладке «Elements». С таким представлением DOM веб-разработчику, конечно, намного удобнее работать. Поэтому инструмента, который DOM представлял бы в виде древовидной структуры нет.
Объекты в этой модели образуются практически из всего, что есть в HTML (тегов, текстового контента, комментариев и т.д.), включая при этом сам документ. Связи между этими объектами в модели формируются на основании того, как HTML-элементы расположены в коде относительно друг друга .
При этом DOM документа после его формирования можно изменять . При изменении DOM браузер практически мгновенно перерисовывает изображение страницы. В результате у нас отрисовка страницы всегда соответствует DOM .
Для чтения и изменения DOM программно браузер предоставляет нам DOM API или, другими словами, программный интерфейс. По-простому DOM API – это набор огромного количества различных объектов, их свойств и методов, которые мы можем использовать для чтения и изменения DOM .
Для работы с DOM в большинстве случаев используется JavaScript, т.к. на сегодняшний день это единственный язык программирования, скрипты на котором могут выполняться в браузере.
Зачем нам нужен DOM API? Он нам нужен для того, чтобы мы могли с помощью JavaScript изменять страницу на «лету», т.е. делать её динамической и интерактивной.
DOM API предоставляет нам (разработчикам) огромное количество методов, с помощью которых мы можем менять всё что есть на странице, а также взаимодействовать с пользователем. Т.е. данный программный интерфейс позволяет нам создавать сложные интерфейсы, формы, выполнять обработку действий пользователей, добавлять и удалять различные элементы на странице, изменять их содержимое, свойства (атрибуты), и многое другое.
Сейчас в вебе практически нет сайтов в сценариях которых отсутствовала бы работа с DOM.
Из чего состоит HTML-код страницы
Перед тем, как перейти к изучению объектной модели документа необходимо сначала вспомнить, что из себя представляет исходный код веб-страницы (HTML-документа).
Исходный код веб-страницы состоит из тегов, атрибутов, комментариев и текста. Теги — это базовая синтаксическая конструкция HTML. Большинство из них являются парными. В этом случае один из них является открывающим, а другой – закрывающим. Одна такая пара тегов образует HTML-элемент. HTML-элементы могут иметь дополнительные параметры – атрибуты.
В документе для создания определённой разметки одни элементы находятся внутри других. В результате HTML-документ можно представить как множество вложенных друг в друга HTML-элементов.
В качестве примера рассмотрим следующий HTML код:
В этом коде корневым элементом является html . В него вложены элементы head и body . Элемент head содержит title , а body – h1 и div . Элемент div в свою очередь содержит h2 и p .
Теперь рассмотрим, как браузер на основании HTML-кода строит DOM-дерево.
Как строится DOM-дерево документа
Как уже было описано выше браузер строит дерево на основе HTML-элементов и других сущностей исходного кода страницы. При выполнении этого процесса он учитывает вложенность элементов друг в друга.
В результате браузер полученное DOM-дерево использует не только в своей работе, но также предоставляет нам API для удобной работы с ним через JavaScript.
При строительстве DOM браузер создаёт из HTML-элементов, текста, комментариев и других сущностей этого языка объекты (узлы DOM-дерева).
В большинстве случаев веб-разработчиков интересуют только объекты (узлы), образованные из HTML-элементов.
При этом браузер не просто создаёт объекты из HTML-элементов, а также связывает их между собой определёнными связями в зависимости от того, как каждый из них относится к другому в коде.
Элементы, которые находятся непосредственно в некотором элементе являются по отношению к нему детьми. А он для каждого из них является родителем. Кроме этого, все эти элементы по отношению друг к другу являются сиблингами (братьями).
При этом в HTML любой элемент всегда имеет одного родителя (HTML-элемент, в котором он непосредственно расположен). В HTML у элемента не может быть несколько родителей. Исключение составляет только элемент html . У него нет родителя.
Чтобы получить DOM-дерево так как его строит браузер, необходимо просто «выстроить» все элементы в зависимости от их отношения друг к другу.
Создание DOM-дерева выполняется сверху вниз.
При этом корнем DOM-дерева всегда является сам документ (узел document ). Далее дерево строится в зависимости от структуры HTML кода.
Например, HTML-код, который мы рассматривали выше будет иметь следующее DOM-дерево:
В самом верху этого дерева находится узел document . Данный узел связан с html , он является его ребёнком. Узел html образован элементом html ( <html>. </html> ). Узлы head ( <head>. </head> ) и body ( <body>. </body> ) имеют родительскую связь с html . По отношению друг ту другу они являются сиблингами, т.к. имеют одного родителя. Узел head связан с title ( lt;title>. </title> ), он является его ребёнком. Узлы h1 и div связаны с body , для них он является родителем. Узел div связан с h2 ( <h2>. </h2> ) и p ( <p>. </p> ), они являются его детьми.
Начинается дерево как было уже отмечено выше с объекта (узла) document . Он в свою очередь имеет один дочерний узел, образованный элементом html ( <html>. </html> ). Элементы head ( <head>. </head> ) и body ( <body>. </body> ) находятся в html и, следовательно, являются его детьми. Далее узел head является родительским для title ( lt;title>. </title> ). Элементы h1 и div вложены в body , значит они являются его детьми. В div непосредственно расположены элементы h2 ( <h2>. </h2> ) и p ( <p>. </p> ). Это значит, что узел div для каждого из них является родительским.
Вот так просто строится DOM-дерево в браузере на основании HTML-кода.
Зачем нужно знать, как строится DOM дерево? Во-первых, это понимание той среды, в которой вы хотите что-то изменять. Во-вторых, большинство действий при работе с DOM сводится к поиску (выбору) нужных элементов. Не зная как устроено DOM-дерево и связи между узлами найти какой-то определенный элемент в нём будет достаточно затруднительно.
Объектная модель документа, или «DOM», является программным интерфейсом доступа к элементам веб-страниц. По сути, это API страницы, позволяющий читать и манипулировать содержимым, структурой и стилями страницы. Давайте разберемся как это устроено и как это работает.
Как строится веб-страница?
- CSSOM, представление стилей, связанных с элементами
- DOM, представление элементов
Из чего состоит DOM?
Давайте рассмотрим этот HTML-документ в качестве примера:
Этот документ может быть представлен в виде следующего дерева узлов:
Чем DOM не является
В приведенном выше примере кажется, что DOM является отображением 1: 1 исходного HTML-документа. Однако, как я уже говорил, есть различия. Чтобы полностью понять, что такое DOM, нам нужно взглянуть на то, чем он не является.
DOM не является копией исходного HTML
Хотя DOM создан из HTML-документа, он не всегда точно такой же. Есть два случая, в которых DOM может отличаться от исходного HTML.
1. Когда HTML содержит ошибки разметки
Рассмотрим в качестве примера этот HTML-документ:
В документе отсутствуют элементы <head> и <body> , что является обязательным требованием для HTML. Но если мы посмотрим на получившееся дерево DOM, то увидим, что это было исправлено:
2. Когда DOM модифицируется кодом Javascript
Помимо того, что DOM является интерфейсом для просмотра содержимого документа HTML, он сам также может быть изменен.
Мы можем, например, создать дополнительные узлы для DOM, используя Javascript.
Этот код изменит DOM, но изменения не отобразятся в документе HTML .
В окне просмотра браузера вы видите дерево рендеринга, которое, как я уже говорил, является комбинацией DOM и CSSOM. Чем отличается DOM от дерева рендеринга, так это то, что последнее состоит только из того, что в конечном итоге будет отображено на экране.
Поскольку дерево рендеринга имеет отношение только к тому, что отображается, оно исключает элементы, которые визуально скрыты. Например, элементы, у которых есть стили с display: none.
DOM будет включать элемент <p> :
Однако дерево рендеринга и, следовательно, то, что видно в окне просмотра, не будет включено в этот элемент.
Это различие немного меньше, потому что инспектор элементов DevTools обеспечивает самое близкое приближение к DOM, которое мы имеем в браузере. Однако инспектор DevTools содержит дополнительную информацию, которой нет в DOM.
Несмотря на то, что псевдоэлементы не являются частью DOM, они есть в нашем инспекторе элементов devtools.
Резюме
Хотя DOM похож на другие формы исходного документа HTML, он отличается по ряду причин:
Основным инструментом работы и динамических изменений на странице является DOM (Document Object Model) - объектная модель, используемая для XML/HTML-документов.
Согласно DOM-модели, документ является иерархией.
Каждый HTML-тег образует отдельный элемент-узел, каждый фрагмент текста - текстовый элемент, и т.п.
Проще говоря, DOM - это представление документа в виде дерева тегов. Это дерево образуется за счет вложенной структуры тегов плюс текстовые фрагменты страницы, каждый из которых образует отдельный узел.
Простейший DOM
Построим, для начала, дерево DOM для следующего документа.
Самый внешний тег - <html> , поэтому дерево начинает расти от него.
Внутри <html> находятся два узла: <head> и <body> - они становятся дочерними узлами для <html> .
Теги образуют узлы-элементы (element node). Текст представлен текстовыми узлами (text node). И то и другое - равноправные узлы дерева DOM.
Пример посложнее
Рассмотрим теперь более жизненную страничку:
Корневым элементом иерархии является html . У него есть два потомка. Первый - head , второй - body . И так далее, каждый вложенный тег является потомком тега выше:
На этом рисунке синим цветом обозначены элементы-узлы, черным - текстовые элементы.
Дерево образовано за счет синих элементов-узлов - тегов HTML.
А вот так выглядит дерево, если изобразить его прямо на HTML-страничке:
Кстати, дерево на этом рисунке не учитывает текст, состоящий из одних пробельных символов. Например, такой текстовый узел должен идти сразу после <ol> . DOM, не содержащий таких "пустых" узлов, называют "нормализованным".
Пример с атрибутами и DOCTYPE
Рассмотрим чуть более сложный документ.
Верхний тег - html , у него дети head и body , и так далее. Получается дерево тегов:
В этом примере у узлов есть атрибуты: style , class , id . Вообще говоря, атрибуты тоже считаются узлами в DOM-модели, родителем которых является элемент DOM, у которого они указаны.
Однако, в веб-программировании в эти дебри обычно не лезут, и считают атрибуты просто свойствами DOM-узла, которые, как мы увидим в дальнейшем, можно устанавливать и менять по желанию программиста.
Вообще-то это секрет, но DOCTYPE тоже является DOM-узлом, и находится в дереве DOM слева от HTML (на рисунке этот факт скрыт).
P.S. Насчет секрета - конечно, шутка, но об этом и правда далеко не все знают. Сложно придумать, где такое знание может пригодиться.
Нормализация в различных браузерах
При разборе HTML Internet Explorer сразу создает нормализованный DOM, в котором не создаются узлы из пустого текста.
Firefox - другого мнения, он создает DOM-элемент из каждого текстового фрагмента.
Поэтому в Firefox дерево этого документа выглядит так:
На рисунке для краткости текстовые узлы обозначены просто решеткой. У body вместо 3 появилось 7 детей.
Opera тоже имеет чем похвастаться. Она может добавить лишний пустой элемент "просто от себя".
Чтобы это увидеть - откройте документ по этой ссылке. Он выдает число дочерних узлов document.body , включая текстовые узлы.
У меня получается 3 для IE, 7 для Firefox и 8 (!?) для Opera.
На практике эта несовместимость не создает больших проблем, но нужно о ней помнить. Например, разница может проявить себя в случае перебора узлов дерева.
Возможности, которые дает DOM
Зачем, кроме красивых рисунков, нужна иерархическая модель DOM?
Каждый DOM-элемент является объектом и предоставляет свойства для манипуляции своим содержимым, для доступа к родителям и потомкам.
Для манипуляций с DOM используется объект document .
Используя document , можно получать нужный элемент дерева и менять его содержание.
Например, этот код получает первый элемент с тэгом ol , последовательно удаляет два элемента списка и затем добавляет их в обратном порядке:
Для примера работы такого скрипта - кликните на тексте на лосиной cтраничке
В старых руководствах и скриптах можно встретить модификацию HTML-кода страницы напрямую вызовом document.write .
В современных скриптах этот метод почти не используется, случаи его правильного применения можно пересчитать по пальцам.
Избегайте document.write.. Кроме случаев, когда вы действительно знаете, что делаете (а зачем тогда читаете самоучитель - вы и так гуру)
Разберем подробнее способы доступа и свойства элементов DOM.
Доступ к элементам
Любой доступ и изменения DOM берут свое начало от объекта document .
Начнем с вершины дерева.
document.documentElement
Самый верхний тег. В случае корректной HTML-страницы, это будет <html> .
document.body
Тег <body> , если есть в документе (обязан быть).
Это свойство работает немного по-другому, если установлен DOCTYPE Strict. Обычно проще поставить loose DOCTYPE.Следующий пример при нажатии на кнопку выдаст текстовое представление объектов document.documentElement и document.body . Сама строка зависит от браузера, хотя объекты везде одни и те же.
Типы DOM-элементов
У каждого элемента в DOM-модели есть тип. Его номер хранится в атрибуте elem.nodeType
Всего в DOM различают 12 типов элементов.
Обычно используется только один: Node.ELEMENT_NODE , номер которого равен 1. Элементам этого типа соответствуют HTML-теги.
Иногда полезен еще тип Node.TEXT_NODE , который равен 3. Это текстовые элементы.
Остальные типы в javascript программировании не используются.
Следующий пример при нажатии на кнопку выведет типы document.documentElement , а затем тип последнего потомка узла document.body . Им является текстовый узел.
Пример
Например, вот так выглядел бы в браузере документ из примера выше, если каждый видимый элемент обвести рамкой с цифрой nodeType в правом верхнем углу.
Здесь показаны только элементы внутри body , т.к только они отображаются на странице. Для элементов типа 1 (теги) в скобочках указан соответствующий тег, для текстовых элементов (тип 3) - стоит просто цифра.
Дочерние элементы
С вершины дерева можно пойти дальше вниз. Для этого каждый DOM-узел содержит массив всех детей, отдельно - ссылки на первого и последнего ребенка и еще ряд полезных свойств.
-
Все дочерние элементы, включая текстовые находятся в массиве childNodes .
В следующем примере цикл перебирает всех детей document.body .
В общем. если взять отдельно <body> с детьми из нормализованного DOM - такая картинка получается ОТ <body> :
И такая - для ссылок наверх и между узлами:
- Синяя линия - массив childNodes
- Зеленые линии - свойства firstChild , lastChild .
- Красная линия - свойство parentNode
- Бордовая и лавандовая линии внизу - previousSibling , nextSibling
Этих свойств вполне хватает для удобного обращения к соседям.
Свойства элементов
У DOM-элементов есть масса свойств. Обычно используется максимум треть из них. Некоторые из них можно читать и устанавливать, другие - только читать.
Есть еще и третий вариант, встречающийся в IE - когда устанавливать свойство можно только во время создания элемента.
Рассмотрим здесь еще некоторые (не все) свойства элементов, полезные при работе с DOM.
tagName
Атрибут есть у элементов-тегов и содержит имя тега в верхнем регистре, только для чтения.
style
Это свойство управляет стилем. Оно аналогично установке стиля в CSS.
Например, можно установить element.style.width :
Исходный код этой кнопки:
Обработчик события onclick обращается в этом примере к свойству this.style.width , т.к значением this в обработчике события является текущий элемент (т.е сама кнопка). Подробнее об этом - во введении в события.Есть общее правило замены - если CSS-атрибут имеет дефисы, то для установки style нужно заменить их на верхний регистр букв.
Например, для установки свойства z-index в 1000, нужно поставить:
innerHTML
Когда-то это свойство поддерживалось только в IE. Теперь его поддерживают все современные браузеры.
Оно содержит весь HTML-код внутри узла, и его можно менять.
Свойство innerHTML применяется, в основном, для динамического изменения содержания страницы, например:
Пожалуй, innerHTML - одно из наиболее часто используемых свойств DOM-элемента.
className
Это свойство задает класс элемента. Оно полностью аналогично html-атрибуту "class".
onclick , onkeypress, onfocus .
.. И другие свойства, начинающиеся на "on. ", хранят функции-обработчики соответствующих событий. Например, можно присвоить обработчик события onclick .
Подробнее об этих свойствах и обработчиках событий - см. введение в события.
Читайте также: