Internet Explorer 5.0 и Document Object Model

Алексей Федоров

DOM или DHTML Object Model?

Преимущества DOM

Реализация DOM

Навигация по ветвям

Создание элементов и ветвей

Манипуляции с узлами

Заключение

 

Принятие комитетом World Wide Web Consortium (W3C) стандарта на объектную модель документа (Document Object Model, DOM) привнесло ряд дополнений в объектную модель браузера Microsoft Internet Explorer. Document Object Model — это интерфейс, не зависящий от платформы и языка, позволяющий скриптовым программам иметь доступ к содержимому, структуре и стилям документа. DOM включает модель представления HTML- и XML-документов, а также описывает интерфейсы, необходимые для доступа к ним и манипуляции их содержимым. Разработчики могут использовать интерфейсы DOM совместно с объектной моделью Dynamic HTML.

DOM или DHTML Object Model?

В Internet Explorer 4.0 впервые появилась объектная модель, известная под названием Dynamic HTML Object Model, которая обеспечивает программный доступ практически ко всем элементам страницы и ко всем их атрибутам. Данная объектная модель включает также событийную модель, которая и превращает HTML в Dynamic HTML. Эта объектная модель поддерживается и в Internet Explorer 5.0. Document Object Model, расширяющая Dynamic HTML Object Model, позволяет программно обращаться ко всем элементам и их атрибутам.

Document Object Model — это эволюция Dynamic HTML Object Model, модель, которая обеспечивает четкую структуризацию документа, его иерархическое представление в виде точек и ветвей. Разработчики, знакомые с Dynamic HTML Object Model, без труда смогут использовать новые методы Document Object Model для программного управления содержимым документа.

В начало

В начало

Преимущества DOM

Использование DOM дает разработчикам ряд преимуществ при манипуляции иерархической структурой документа. Используя DOM, разработчики могут:

  • перемещать часть иерархии документа в другое место без уничтожения содержимого документа или повторного его создания;

  • создавать элементы и вставлять их в любом месте документа;

  • перестраивать документ, вставлять новые ветви или изменять существующие.

Возможность перемещения частей документа без уничтожения его содержимого и повторного создания документа позволяет сократить размер скриптовой программы и сделать сам динамический документ более эффективным. Рассмотрим следующий пример. Пусть у нас имеется следующая таблица:

<table id=”dTable” width=”90%” border>
   <tr>
      <td>Ячейка 1.1</td> 
      <td>Ячейка 1.2</td> 
   </tr>
   <tr>
       <td>Ячейка 2.1</td> 
       <td>Ячейка 2.2</td> 
   </tr>
   <tr style=”background-color : #a7c7b7;”>
       <td>Ячейка 3.1</td> 
       <td>Ячейка 3.2</td> 
   </tr>
</table>

Для того чтобы при использовании Dynamic HTML мы могли поменять местами второй и третий ряд, нам нужно выполнить довольно много действий. Во-первых, мы должны сохранить содержимое нижнего ряда (свойство innerHTML), уничтожить сам ряд, затем воссоздать сохраненный ряд в новом месте, изменив значения ячеек и рядов таблицы. Вот код, который иллюстрирует эти действия:

<script defer>
// Индекс нижнего ряда
  var Index = dTable.rows(2).rowIndex;
  function move()
  {
// Сохраним содержимое нижнего ряда
    Cell1 = dTable.rows[Index].cells[0].innerHTML;
    Cell2 = dTable.rows[Index].cells[1].innerHTML;
// Удалим нижний ряд
    dTable.deleteRow(Index);
// Index = Index - 1
    Index—; 
// Вставим ряд
    dTable.insertRow(Index); 
// Зададим цвет фона ячеек
    dTable.rows(Index).style.background = “#a7c7b7”;
// Вставим 2 ячейки
    dTable.rows(Index).insertCell(0);
    dTable.rows(Index).insertCell(1);
// И их содержимое
    dTable.rows(Index).cells(0).innerHTML += Cell1;
    dTable.rows(Index).cells(1).innerHTML += Cell2;
  }
</script>

С использованием методов DOM данная задача может быть решена существенно более эффективно — мы просто изменяем позиции двух рядов в иерархии элементов документа, применяя метод swapNode. Предыдущий ряд определяется через свойство previousSibling:

<script defer>
// Нижний ряд
   var Row = dTable.rows(2);
   function move()
   {
// Поменяем ряды местами
    Row.swapNode(Row.previousSibling);
   }
</script>

Естественно, что использование DOM в данном примере дает нам не только более компактный код, но и существенно сокращает время, требуемое для реализации данной задачи.

В начало

В начало

Реализация DOM

Интерфейс Document Object Model в Internet Explorer 5.0 позволяет программистам иметь доступ к иерархической структуре документа. Под ветвью понимаются ссылки на элемент, атрибут или строку текста. Следует отметить, что DOM не обеспечивает всех возможностей Dynamic HTML Object Model, в частности, в DOM не поддерживаются события. Ниже мы рассмотрим, как DOM реализована в Internet Explorer 5.0, и сравним ее с Dynamic HTML Object Model.

В Internet Explorer 5.0 поддержка Document Object Model реализована в виде свойств, методов и коллекций. Сначала мы перечислим их, а затем рассмотрим более подробно.

В начало

В начало

Навигация по ветвям

Для навигации по ветвям документа DOM предлагает программистам несколько свойств и коллекций. Рассмотрим следующий пример. Пусть у нас имеется таблица, состоящая из трех рядов по две колонки:

<table id=”dTable” >
<tr><td>Ячейка 1.1</td><td>Ячейка 1.2</td></tr>
<tr><td>Ячейка 2.1</td><td>Ячейка 2.2</td></tr>
<tr><td>Ячейка 3.1</td><td>Ячейка 3.2</td></tr>
</table>

Данная таблица имеет идентификатор dTable (заданный атрибутом id).

Используя DOM, мы можем узнать число дочерних элементов:

ch = dTable.childNodes.length;

В данном случае у таблицы (элемент TABLE) будет один дочерний элемент — TBODY, у элемента TBODY, в свою очередь, 3 дочерних элемента — TR, каждый из которых имеет по два дочерних элемента — TD. Отметим, что элемент TBODY вставляется Internet Explorer автоматически.

Также мы можем получить доступ к родительскому элементу — через свойство parentNode и к первому и последнему дочернему элементу — через свойства firstChild и lastChild. Дочерние элементы от второго до предпоследнего могут быть получены из значения свойства nextSibling. Таким образом, пока nextSibling не равно lastChild, мы можем перемещаться по коллекции дочерних элементов. Также для навигации по коллекции мы можем использовать цикл, счетчиком которого будет значение свойства length коллекции childNodes. Каждый элемент будет доступен как значение свойства nextSibling.

Для получения родительского объекта мы можем использовать свойство parentNode, которое аналогично свойству parentElement в DHTML.

Значение текущего элемента может быть получено как значение свойства nodeValue, что эквивалентно свойствам innerHTML и innerText в DHTML.

В начало

В начало

Создание элементов и ветвей

DOM предоставляет разработчикам ряд методов для создания элементов и ветвей. К ним относятся: createElement и createTextNode. Оба эти метода являются методами объекта document, и соответственно, доступны в HTML-документах, описателях поведения (DHTML Behaviors) и HTML-приложениях (HTA).

Вспомним, что DHTML Object Model содержит свойства innerHTML и outerHTML, позволяющие добавлять новые элементы, а также методы, специфичные для отдельных элементов, например insertRow и insertCell для элемента TABLE. При использовании DOM вам потребуется только один метод — createElement.

На следующем примере показано, как использовать методы createElement, createTextNode и appendChild для добавления новых элементов к списку.

<script defer>
   function add()
   {
    // Создадим новый элемент
    li = document.createElement(“li”);
    // Опишем его содержимое
    txt = document.createTextNode(“List Element X”);
    // Добавим содержимое
    li.appendChild(txt);
    // И сам элемент
    dList.appendChild(li);
   }
</script>
<body>
  <h1 align=”center”>DOM — Добавление элементов </h1>
  <ul id=”dList”>
    <li onClick=”add()”>List Element 1
    <li>List Element 2
    <li>List Element 3
  </ul>
</body>

Отметим, что при использовании свойства innerHTML код будет короче:

<script defer>
  function add()
  {
    dList.innerHTML += “<li>List Element X”
  }
</script>

Говоря о методе createElement, следует напомнить, что он был доступен и в Internet Explorer 4.0, но только для создания элементов AREA, IMG и OPTION. В Internet Explorer 5.0 с помощью этого метода возможно создание всех элементов. Кроме того, свойства с атрибутом «только чтение», как, например, свойство id, доступны для записи у элементов, создаваемых методом createElement. Естественно, что задание значений таких свойств должно происходить перед вставкой элементов в иерархию элементов документа.

Следует иметь в виду, что использование метода createElement может привести к созданию неверного HTML-кода. Это касается в первую очередь таблиц. Для таблиц требуется наличие двух элементов — TABLE и TBODY. Напомним, что, используя DHTML Object Model, мы можем создать таблицу с помощью свойства innerHTML, методов insertRow и insertCell, а также коллекций rows и cells. Ниже показано, как это можно сделать:

<script defer>
  function createTable()
  {
    var tableTag = “<TABLE id=’dTable’ border></TABLE>”;
    document.body.innerHTML += tableTag;
// Теперь таблица dTable программно доступна
    dTable.insertRow(0); // Вставим один ряд
    dTable.rows(0).insertCell(0); // Ячейка 1
    dTable.rows(0).insertCell(1); // Ячейка 2
    dTable.rows(0).cells(0).innerText = “Ячейка 1.1”
    dTable.rows(0).cells(1).innerText = “Ячейка 1.2”
  }
</script>

В этом случае элемент TBODY будет создан автоматически как часть создаваемой объектной модели таблицы. Вот HTML-код, который получится в результате:

<TABLE id=’dTable’ border>
<TBODY>
<TR><TD>Ячейка 1.1</TD><TD>Ячейка 1.2</TD></TR>
</TBODY>
</TABLE>

При использовании средств DOM мы должны указать элемент TBODY самостоятельно. Иначе будет сформирована неверная иерархия объектов, что может привести к ошибкам обработки документа. Ниже показано, как создать аналогичную таблицу средствами DOM.

  function createTable()
  {
// Создадим необходимые элементы
    var tableTag = document.createElement(“TABLE”);
    var tbodyTag = document.createElement(“TBODY”);
    var rowTag = document.createElement(“TR”);
    var cellTag1 = document.createElement(“TD”);
// Также можно использовать метод cloneNode!
    var cellTag2 = document.createElement(“TD”);
// Содержимое ячеек
    txt = document.createTextNode(“Ячейка 1.1”); 
    cellTag1.appendChild(txt);
    txt = document.createTextNode(“Ячейка 1.2”); 
    cellTag2.appendChild(txt);
// Добавим ячейки в ряд
    rowTag.appendChild(cellTag1);
    rowTag.appendChild(cellTag2);
// Добавим TBODY
    tableTag.appendChild(tbodyTag);
// Добавим ряд
    tbodyTag.appendChild(rowTag);
// и всю таблицу
    document.body.appendChild(tableTag);
  }
</script>

Отметим, что в приведенном выше коде мы вручную создаем элемент TBODY.

В начало

В начало

Манипуляции с узлами

Объектная модель DOM предоставляет ряд методов для манипуляций с узлами. К этим методам относятся: cloneNode, removeNode, replaceNode и swapNode. Перечисленные здесь методы позволяют копировать, перемещать и удалять узлы. Начнем с метода swapNode. Ниже показан пример перемены мест двух параграфов.

 <script defer>
   function addItem()
   {
     para2.swapNode(para1);
   }
 </script>
</head>
<body>
 <button onClick=”addItem();”>Поменять</button>
 <br>
 <p id=”para1">Первый параграф</p>
 <p id=”para2">Второй параграф</p>
</body>

Рассмотрим еще один пример. Пусть у нас есть два параграфа с идентификаторами para1 и para2. Нажатие кнопки «Добавить» приводит к созданию нового параграфа, вставке его в документ, замене содержимого второго параграфа на содержимое нового и перемене мест между первым и вторым параграфами.

Вот код программы, выполняющей перечисленные действия:

<script defer>
  function addItem()
  {
// Создадим новый параграф
    var newP = document.createElement(“P”);
// Добавим содержимое
    var txt = document.createTextNode(“Новый параграф”);
    newP.appendChild(txt);
// Вставим параграф в документ
    document.body.appendChild(newP);
// Заменим параграф 2 на новый
    para2.replaceNode(newP);
// и поменяем местами с первым
    newP.swapNode(para1);
  }
 </script>
</head>
<body>
 <button onClick=”addItem();”>Добавить</button>
 <br>
 <p id=”para1">Первый параграф</p>
 <p id=”para2">Второй параграф</p>
</body>

Отметим, что методы replaceNode и swapNode используются для обмена содержимым между ветвями документа. Различия в этих двух методах заключаются в том, что replaceNode удаляет ветвь, вызвавшую данный метод, а swapNode меняет две ветви местами.

Рассмотрим пример использования метода cloneNode для клонирования (копирования) заданной ветви. Пусть у нас есть таблица, состоящая из трех рядов по две колонки. Мы будем использовать метод cloneNode для копирования первого ряда таблицы и добавления его в конец таблицы. Вот код этого примера:

<script defer>
  function clone()
  {
// Скопируем первый ряд
    var row = dTable.rows(0).cloneNode(true);
// dTable.firstChild = TBODY !
// и добавим его в конец таблицы
    dTable.firstChild.appendChild(row);
  }
 </script>
</head>
<body>
 <button onClick=”clone();”>Клонировать</button>
 <br>
 <table border id=”dTable”>
    <tr><td>Ячейка 1.1</td><td>Ячейка 1.2</td></tr>
    <tr><td>Ячейка 2.1</td><td>Ячейка 2.2</td></tr>
    <tr><td>Ячейка 3.1</td><td>Ячейка 3.2</td></tr>
</table>

Отметим, что добавление рядов происходит к элементу TBODY, а не TABLE, поэтому мы используем метод appendChild элемента dTable.firstChild, которым и является элемент TBODY.

Если же мы захотим предусмотреть возможность удаления ранее скопированных элементов, то нам нужно написать следующий код:

function remove()
  {
    var tBody = dTable.firstChild;
    var last = tBody.lastChild;
    last.removeNode(last.lastChild);
  }

Обратите внимание на то, как мы используем взаимоотношения между элементами. Сначала мы находим элемент TBODY:

var tBody = dTable.firstChild;

Затем — последний ряд:

var last = tBody.lastChild;

И уже после этого удаляем его, используя метод removeNode.

В начало

В начало

Заключение

Использование DOM и DHTML Object Model дает нам практически неограниченные возможности для манипулирования содержимым документа после его загрузки. За счет непосредственного доступа к иерархии элементов в документе достигается высокая скорость работы программы, а сам код становится намного компактнее.

Полную спецификацию Document Object Model можно получить на Web-узле World Wide Web Consortium по адресу: http://www.w3c.org/DOM/

В этом номере также публикуются статьи, посвященные основным новинкам, представляющим интерес для программистов, — «Microsoft Internet Explorer 5.0 для разработчиков», и новинкам в скриптовых языках — «Internet Explorer 5.0 — Новые версии скриптовых языков»

КомпьютерПресс 5'1999

1999 1 2 3 4 5 6 7 8 9 10 11 12
2000 1 2 3 4 5 6 7 8 9 10 11 12
2001 1 2 3 4 5 6 7 8 9 10 11 12
2002 1 2 3 4 5 6 7 8 9 10 11 12
2003 1 2 3 4 5 6 7 8 9 10 11 12
2004 1 2 3 4 5 6 7 8 9 10 11 12
2005 1 2 3 4 5 6 7 8 9 10 11 12
2006 1 2 3 4 5 6 7 8 9 10 11 12
2007 1 2 3 4 5 6 7 8 9 10 11 12
2008 1 2 3 4 5 6 7 8 9 10 11 12
2009 1 2 3 4 5 6 7 8 9 10 11 12
2010 1 2 3 4 5 6 7 8 9 10 11 12
2011 1 2 3 4 5 6 7 8 9 10 11 12
2012 1 2 3 4 5 6 7 8 9 10 11 12
2013 1 2 3 4 5 6 7 8 9 10 11 12
Популярные статьи
КомпьютерПресс использует