Глаза страшат, а руки делают

ЧАСТЬ ТРЕТЬЯ


32. Введение в DOM

  • что такое DOM;
  • узлы DOM;
  • некоторые свойства узлов;
  • свойства-«паспорта» узлов.

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

Советую внимательно прочитать «историко-теоретическую» часть, даже если она покажется нудной и не относящейся к делу. Когда перейдём к практической части, постараюсь быть проще и конкретнее. Но база для практики необходима.

Что такое DOM

Аббревиатура DOM расшифровывается как Document Object Model (объектная модель документа).

DOM — это программный интерфейс доступа к содержимому HTML, XHTML и XML-документов, то есть представление тэгов и атрибутов HTML, XHTML и XML, а также стилей CSS в виде объектов программирования. С этой моделью работает как JavaScript, так и другие языки web-программирования.

Немного истории

Существует 4 уровня DOM (0, 1, 2 и 3).

Уровень 0 (1996) включал в себя модели DOM, которые существовали до появления уровня 1. В основном это коллекции: document.images, document.forms, document.layers и document.all. Эти модели формально не являются спецификациями DOM, опубликованными W3C. Скорее они представляют информацию о том, что существовало до начала процесса стандартизации.

Уровень 1 (1997) включал также базовые функциональные возможности по обработке XML-документов: многочисленные способы работы с отдельными узлами, работа с инструкциями обработки XML и т.д.

Кроме того, DOM уровня 1 содержит ряд специальных интерфейсов, которые могут обрабатывать отдельные HTML-элементы. Например, можно работать с таблицами HTML, формами, списками выбора и т.д.

В DOM уровня 2 (2002) было добавлено несколько новых возможностей.

Если в DOM уровня 1 отсутствовала поддержка пространств имён, то интерфейсы DOM уровня 2 содержат методы для управления пространствами имён, связанными с требованиями к составлению и обработке XML-документов.

Помимо этого, DOM уровня 2 поддерживает события.

Уровень 2 является текущим уровнем спецификаций DOM, однако W3C рекомендует и некоторые разделы спецификаций уровня 3.

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

Что означает «программный интерфейс»?

Английское слово interface можно перевести как «область контакта». Компьютер, грубо говоря, понимает только две вещи: пустой бит и заполненный бит. Язык, на котором «говорит» компьютер, можно представить как нескончаемую вереницу нулей и единиц, дающих бесконечное количество различных комбинаций.

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

Браузеры работают так же, как и другие компьютерные приложения. Они интерпретируют в «нули и единицы» коды HTML, XML, CSS, скрипты JavaScript, PHP, Perl и т.д. Для работы с этим многоязычием нужна общая платформа. Этой платформой и является DOM — спецификация, не зависящая от конкретного языка программирования или разметки. Это интерфейс, который можно использовать во многих популярных языках программирования, связанных с созданием web-страниц и способных понимать и интерпретировать объекты DOM.

DOM и браузеры

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

DOM и JavaScript

В JavaScript вершиной иерархической лестницы объектов DOM, своеобразным «проводником» в этот интерфейс служит объект document, а объекты DOM становятся его свойствами, свойствами его свойств и т.д. Их также называют узлами DOM.

Узлы DOM

В DOM уровня 2 есть 12 типов узлов. За каждым типом узла DOM закреплена константа с уникальным именем. Большинство узлов предназначено для работы с XML. В сборке HTML — JavaScript, которой мы занимаемся, можно использовать только 5 типов. Но и эта «верхушка айсберга» представляет собой весьма «развесистое дерево», которое не охватить за одно-два занятия.

Полный набор констант типов узлов, определённый в спецификации W3C DOM (голубым подсвечены узлы, доступные для HTML — JavaScript):

Имя константы

Значение

Описание

Node.ELEMENT_NODE

1

Узел элемента (возвращает корневой элемент документа, для HTML-документов это элемент HTML)

Node.ATTRIBUTE_NODE

2

Узел атрибута (возвращает атрибут элемента XML- или HTML-документа)

Node.TEXT_NODE

3

Текстовый узел (#text)

Node.CDATA_SECTION_NODE

4

Узел секции CDATA (XML: альтернативный синтаксис для отображения символьных данных)

Node.ENTITY_REFERENCE_NODE

5

Узел ссылки на раздел

Node.ENTITY_NODE

6

Узел раздела

Node.PROCESSING_INSTRUCTION_NODE

7

Узел директивы XML

Node.COMMENT_NODE

8

Узел комментария

Node.DOCUMENT_NODE

9

Узел документа (основа доступа к содержанию документа и создания его составляющих)

Node.DOCUMENT_TYPE_NODE

10

Узел типа документа (возвращает тип данного документа, т.е. значение тэга DOCTYPE)

Node.DOCUMENT_FRAGMENT_NODE

11

Узел фрагмента документа (извлечение части дерева документа, создание нового фрагмента документа, вставка фрагмента в качестве дочернего элемента какого-либо узла и т.п.)

Node.NOTATION_NODE

12

Узел нотации*

* Нотации — это имена, идентифицирующие формат неанализируемых разделов, формат элементов, имеющих атрибут нотации, или прикладную программу, которой адресована директива. (Непонятно? Мне пока тоже не очень.)

Структура документа в модели DOM

Все объекты документа являются узлами DOM. Рассмотрим элементарный документ:

<html>
<head><title>DOM</title></head>
<body>
<h1 align="center">Заголовок</h1>
<p>Текст абзаца</p>
</body>
<html>

Вот схема его DOM-дерева:

Каждый узел может иметь дочерние узлы (на схеме к ним ведут стрелки). Объект document — основание дерева документа — тоже узел, но у него нет родительского узла и имеется ряд свойств и методов, отсутствующих у других узлов. Он имеет один дочерний узел: элемент <html>.

У элемента <html> два дочерних узла: <head> и <body>, для которых дочерними становятся все элементы, содержащиеся в них.

Внимание!

«Элемент» и «тэг» не синонимы. Тэг — это знак разметки: <p> и </p> — это два разных тэга. А элемент — объект, помеченный этими тэгами: <p>Текст абзаца</p>.

Элементы <title>, <h1> и <p> содержат внутри себя текст. Это их дочерние текстовые узлы. У элемента <h1> есть также атрибут: align="center". Узлы атрибутов — это тоже дочерние узлы элементов, которые их содержат.

При работе с узлами DOM-дерева используются их свойства и методы.

Некоторые свойства узлов

Маленькое вступление

Ещё раз повторю: когда мы обращаемся в скриптах к элементам страницы, то имеем дело не только с языком Javascript, но и с внедрённым в него интерфейсом DOM. Иногда необходимо отдавать себе в этом отчёт, иногда можно и забыть, «что говорим прозой».

Некоторыми свойствами и методами из объектной модели DOM мы уже таким образом пользовались. Поэтому временами я буду давать ссылки на предыдущие уроки.

В этом уроке мы не будем идти «академическим» путём, рассматривая все свойства всех узлов во всех браузерах. Для начала познакомимся с самыми практичными и «бесконфликтными» из них.

Именно поэтому не будем начинать, как принято, с «основных свойств»: nodeName и nodeValue.

tagName

Возвращает строку с именем тэга элемента. Все значения tagName содержат символы только верхнего регистра.

Синтаксис

элемент.tagName

Пример

<!-- Вставим <span>, чтобы имя было не из одной буквы. -->
<p><span id="testTagName">Тестируем свойство tagName</span></p>
<p>
<script type="text/javascript">
document.write(document.getElementById("testTagName").tagName)
</script>
</p>

Результат

Тестируем свойство tagName

innerHTML

С этим свойством мы уже встречались (см. Урок 10). А теперь понимаем, откуда оно взялось: «из дома».

Даёт доступ к содержимому элемента. Задаёт не только текстовое содержание, но и все тэги HTML, находящиеся внутри элемента.

Это свойство не только для чтения, но и для изменения содержимого.

Примечание

В IE для ряда элементов innerHTML работает только для чтения: это все табличные элементы, за исключением <td> и <th>, а также <title> и <frameset>.

Например, мы создали пустую таблицу без элемента <td> и хотим программно вставить его в  <tr> через innerHTML:

<html>
<head></head>
<body onload=
"document.getElementById('test').innerHTML = '<td>тестовая строка</td>'">
<table>
<tr id=
"test"></tr>
</table>

</body>
</html>

IE выдаст «неизвестную ошибку выполнения», а остальные браузеры произведут вставку.

В то же время, если мы запросим существующее содержимое элемента <tr>, например, через alert(document.getElementById('id').innerHTML), то в IE это сработает.

Синтаксис

элемент.innerHTML = "назначенный текст"

Пример

<!-- читаем текст отсюда
(исходный элемент делаем невидимым) -->

<p style="display: none;" id="testInnerHTML"><b style="color: red;">Тестируем свойство innerHTML</b></p>
<!-- вставляем его сюда -->
<p id="target">Абзац для вставки</p>
<script type="text/javascript">
// Эта функция читает текст и вставляет его в заданный абзац.
function testRead() {
document.getElementById("target").innerHTML = document.getElementById("testInnerHTML").innerHTML
}
// Эта функция изменяет текст заданного абзаца.
function
testChange() {
document.getElementById("target").innerHTML = "<span style='color: blue;'>Перекрашиваем и меняем текст</span>"
}
// Эта функция возвращает свойство в исходное положение.
function
testReset() {
document.getElementById("target").innerHTML = "Абзац для вставки"
}
</script>
<form>
<input type=
"button" value="прочитать innerHTML" onClick="testRead();">
<input type=
"button" value="изменить innerHTML" onClick="testChange();">
<input type=
"button" value="сброс" onClick="testReset();">
</form>

Абзац для вставки

Примечание

Есть ещё свойство innerText, которое включает только текстовое содержимое, очищенное от вложенных тэгов. Но оно работает только в IE.

style

Об этом свойстве мы тоже уже говорили, и даже довольно подробно.

Оно позволяет управлять настройками стилей CSS для данного элемента. Значением свойства является объект style, чьи собственные свойства позволяют получать и изменять установки стилей.

Синтаксис

элемент.style.свойствоСтиля = "значение"

свойствоСтиля — любое свойство стиля CSS.

"значение" — любое существующее значение свойства стиля

Примечание

напомню, что дефисы в значении стилей заменяются в JavaScript на заглавные буквы:

text-align = textAlign

background-color = backgroundColor

и т.д.

Примеры можно посмотреть в 13 уроке.

className

Это свойство тоже взаимодействует со стилями CSS, оно задаёт класс элемента из существующего набора таблицы стилей.

Синтаксис

элемент.className = "имя класса"

"имя класса" — любой класс, существуюший в тэге <style> или в прикреплённом файле.css.

«Паспорта» узлов

Как я уже говорил выше, узлы бывают разных типов. В сборке HTML — JavaScript используются 5 типов узлов:

Тип

Значение константы

Возвращаемое значение

Элемент

1

Тэг элемента

Атрибут

2

Имя атрибута

Текст

3

#text

Комментарий

8

#comment

Документ

9

#document

Каждый узел, образно говоря, имеет свой «паспорт», состоящий из трёх свойств: nodeType, nodeName и nodeValue.

Примечание 1

Эти свойства пока работают криво: в каждой избушке (браузере) свои погремушки. По мере «вгрызания» в материал будем знакомиться с глюками и строить обходные функции.

Примечание 2

Эти свойства формально поддерживаются и узлами атрибутов, но с атрибутами они работают не всегда корректно: у атрибутов есть свои особые «паспорта», данные которых не всегда совпадают с данными этих свойств.

nodeType

Возвращает значение константы узла.

nodeName

У элементов возвращает имя тэга прописными буквами, у других узлов — их имена, начинающиеся с «решётки».

nodeValue

У текстовых узлов и комментариев возвращает строку текста, содержащуюся в них, у других — null.

Сводная таблица возвращаемых значений

Узел

nodeType

nodeName

nodeValue

Элемент

1

ИМЯ_ТЭГА

null

Текст

3

#text

строка текста

Комментарий

8

#comment

строка текста

Документ

9

#document

null

Примечание

Значения свойства nodeName для комментария и документа поддерживает только IE. Остальные браузеры возвращают undefined.


Итак, мы узнали:

что такое DOM и из чего он построен.


К следующему уроку >>


 001590