Хотя стандарт DOM появился благодаря желанию иметь общий прикладной ин_ терфейс (API) для DHTML_программирования, модель DOM интересна не только веб_программистам. На самом деле сейчас этот стандарт наиболее интенсивно используется серверными программами на языках Java и C++ для анализа XML_документов и манипуляции ими. Из_за наличия разнообразных вариантов применения стандарт DOM был определен как независимый от языка. В данной книге описывается только привязка DOM API к JavaScript, но необходимо иметь
в виду и некоторые другие моменты. Во_первых, следует отметить, что свойства объекта в привязке к JavaScript обычно соответствуют паре методов get/set
в привязке к другим языкам. Следовательно, когда программист, пишущий на Java, спрашивает вас о методе getFirstChild() интерфейса Node, надо понимать, что в JavaScript привязка Node API не определяет метода getFirstChild(). Вместо этого она просто определяет свойство firstChild, и чтение этого свойства в Java_ Script эквивалентно вызову метода getFirstChild() в Java.
Другая важная особенность привязки DOM API к JavaScript в том, что некото_ рые DOM_объекты ведут себя как JavaScript_массивы. Если интерфейс опреде_ ляет метод с именем item(), то объекты, реализующие этот интерфейс, ведут себя так же, как доступные только для чтения массивы с числовым индексом. Пред_ положим, что в результате чтения свойства childNodes узла получен объект Node_ List. Отдельные объекты Node из списка можно получить двумя способами: во_ первых, передав номер нужного узла методу item(), и во_вторых, рассматривая объект NodeList как массив и обращаясь к нему по индексу. Следующий код ил_ люстрирует эти две возможности:
var n = document.documentElement; // Это объект
Node.
var children = n.childNodes;
// Это объект
NodeList.
var
head
=
children.item(0);
//
Это один из способов использования NodeList.
var
body
=
children[1];
//
Но есть более простой способ!
Аналогично, если у DOM_объекта есть метод namedItem(), передача строки этому методу означает то же самое, что использование строки в качестве индекса мас_ сива. Например, следующие строки кода представляют собой эквивалентные средства доступа к элементу формы:
15.4. Обзор объектной модели W3C DOM
var f = document.forms.namedItem("myform"); var g = document.forms["myform"];
var h = document.forms.myform;
Несмотря на то что существует возможность обращаться к элементам объекта NodeList с использованием нотации массивов, важно помнить, что NodeList – это всего лишь объект, подобный массиву, а не настоящий массив (см. раздел 7.8). Объект NodeList, например, не имеет метода sort().
Стандарт DOM может использоваться различными способами, поэтому разработ_ чики стандарта определили DOM API таким образом, чтобы не ограничивать возможность реализации API другими разработчиками. В частности, стандарт DOM определяет интерфейсы вместо классов. В объектно_ориентированном про_ граммировании класс – это фиксированный тип данных, который должен быть реализован в точном соответствии со своим определением. В то же время интер_ фейс – это коллекция методов и свойств, которые должны быть реализованы вместе. Следовательно, реализация DOM может определять любые классы, кото_ рые считает нужным, но эти классы должны определять методы и свойства раз_ личных DOM_интерфейсов.
Такая архитектура имеет несколько важных следствий. Во_первых, имена клас_ сов в реализации могут не соответствовать напрямую именам интерфейсов в стан_ дарте DOM (и в этой книге). Во_вторых, один класс может реализовывать более одного интерфейса. Рассмотрим, например, объект Document. Этот объект являет_ ся экземпляром некоторого класса, определенного реализацией веб_броузера. Мы не знаем, какой именно это класс, но знаем, что он реализует интерфейс Document; т. е. все методы и свойства, определенные интерфейсом Document, дос_ тупны нам через объект Document. Поскольку веб_броузеры работают с HTML_до_ кументами, мы также знаем, что объект Document реализует интерфейс HTMLDocu_ ment, и нам доступны все методы и свойства, определенные этим интерфейсом. Кроме того, если веб_броузер поддерживает CSS и реализует DOM_модуль CSS, значит, объект Document реализует также DOM_интерфейсы DocumentStyle и Docu_ mentCSS. И если веб_броузер поддерживает модули Events и Views, объект Document реализует также интерфейсы DocumentEvent и DocumentView.
Вообще, в IV части книги основное внимание уделяется описанию объектов, с ко_ торыми сталкиваются JavaScript_программисты, а не более абстрактных интер_ фейсов, определяющих API этих объектов. Таким образом, в четвертой части книги со справочными материалами можно найти разделы с описанием объектов Document и HTMLDocument, но там отсутствуют описания дополнительных интерфей_ сов, таких как DocumentCSS или DocumentView. Описания методов, определяемых этими интерфейсами, просто вставлены в раздел с описанием объекта Document.
Важно также понимать, что т. к. стандарт DOM определяет интерфейсы, а не клас_ сы, он не описывает никаких методов_конструкторов. Если, например, требуется создать новый объект Text для вставки в документ, то нельзя просто написать:
var t = new Text("это новый текстовый узел"); // Такого конструктора нет!
Стандарт DOM не может определять конструкторы, но он определяет в интер_ фейсе Document несколько полезных методов'фабрик (factory methods) для созда_ ния объектов. То есть чтобы создать новый узел Text в документе, надо написать:
var t = document.createTextNode("это новый текстовый узел");
334 Глава 15. Работа с документами
Методы_фабрики, определенные в DOM, имеют имена, которые начинаются со слова «create». Помимо методов_фабрик, определяемых интерфейсом Document, несколько таких методов определяется интерфейсом DOMImplementation и доступ_ но через свойство document.implementation.