DOM - Навигация по узлам

HTML DOM используя отношения между узлами позволяет перемещаться по дереву узлов.

Узлы DOM

Согласно стандарту HTML DOM, все в HTML документе является узлом:

  • Весь документ — узел документа
  • Каждый HTML элемент — узел элемента
  • Текст внутри HTML элементов — узел текста
  • Каждый HTML атрибут — узел атрибута (запрещен)
  • Все комментарии — узлы комментариев

Узлы HTML DOM

С HTML DOM можно получить доступ ко всем узлам при помощи JavaScript. Можно создавать новые узлы, а существующие можно изменять или удалять.

Отношения между узлами

Узлы в дереве DOM имеют иерархические отношения между друг другом.

Чтобы описать эти отношения обычно используют такие понятия как родитель (предок), ребенок (потомок) и родственник (родственный элемент).

  • В дереве узлов самый верхний узел называется корневым узлом
  • У каждого узла, за исключением корневого, всегда есть один и только один предок или родитель
  • У любого узла может быть сколько угодно потомков
  • Родственные или одноуровневые узлы — это узлы, у которых один и тот же предок (родитель)


<html>
  <head>
     <title>Учебник по DOM</title>
  </head>

  <body>
     <h1>Урок первый</h1>
     <p>Привет всем!</p>
  </body>
</html> 

Из HTML кода, представленного выше, мы можем понять следующее:

  • <html> - корневой узел
  • <html> не имеет родителя
  • <html> - родитель узлов <head> и <body>
  • <head> - первый потомок узла <html>
  • <body> - последний потомок узла <html>

также мы видим:

  • <head> имеет одного потомка - <title>
  • <title> имеет одного потомка (текстовый узел) - "Учебник по DOM"
  • <body> имеет двух потомков - <h1> и <p>
  • <h1> имеет одного потомка - "Урок первый"
  • <p> имеет одного потомка - "Привет всем!"
  • <h1> и <p> - родственные (одного уровня) узлы

Перемещение между узлами

Чтобы перемещаться между узлами, используются следующие JavaScript свойства узлов:

  • parentNode
  • childNodes[номер_узла]
  • firstChild
  • lastChild
  • nextSibling
  • previousSibling

Узлы-потомки и значения узлов

Обычная ошибка при работе с DOM — это ожидание, что узел элемента содержит текст.

Пример:


<title id="demo">Учебник по DOM</title>

В приведенном примере узел элемента <title> не содержит текст.

Он содержит текстовый узел со значением "Учебник по DOM".

Получить доступ к значению текстового узла можно при помощи свойства узла innerHTML:


var myTitle = document.getElementById("demo").innerHTML;

Обращение к свойству innerHTML имеет тот же эффект как обращение к nodeValue первого потомка:


var myTitle = document.getElementById("demo").firstChild.nodeValue;

Получить доступ к первому потомку также можно следующим образом:


var myTitle = document.getElementById("demo").childNodes[0].nodeValue; 

Во всех трех следующих примерах извлекается текст элемента <h1> и копируется в элемент <p>.

Пример 1


<html>
<body>

<h1 id="id01">Моя первая страница</h1>
<p id="id02"></p>

<script>
  document.getElementById("id02").innerHTML = document.getElementById("id01").innerHTML;
</script>

</body>
</html>

Пример 2


<html>
<body>

<h1 id="id01">Моя первая страница</h1>
<p id="id02"></p>

<script>
  document.getElementById("id02").innerHTML = document.getElementById("id01").firstChild.nodeValue;
</script>

</body>
</html>

Пример 3


<html>
<body>

<h1 id="id01">Моя первая страница</h1>
<p id="id02"></p>

<script>
  document.getElementById("id02").innerHTML = document.getElementById("id01").childNodes[0].nodeValue;
</script>

</body>
</html>

InnerHTML

В этом учебнике для доступа к содержимому HTML элемента мы используем свойство innerHTML.

Тем не менее, изучение других методов, представленных выше, полезно для лучшего понимания древовидной структуры DOM и того, как осуществляется навигация по его узлам.

Корневые узлы DOM

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

  • document.body – тело документа
  • document.documentElement – весь документ

Пример 1


<html>
<body>

<p>Привет всем!</p>
<div>
  <p>DOM очень полезен!</p>
  <p>Этот пример демонстрирует свойство <b>document.body</b>.</p>
</div>

<script>
  alert(document.body.innerHTML);
</script>

</body>
</html>

Пример 2


<html>
<body>

<p>Привет всем!</p>
<div>
  <p>DOM очень полезен!</p>
  <p>Этот пример демонстрирует свойство <b>document.documentElement</b>.</p>
</div>

<script>
  alert(document.documentElement.innerHTML);
</script>

</body>
</html>

Свойство nodeName

Свойство nodeName определяет имя узла.

  • nodeName — свойство только для чтения
  • nodeName узла элемента — это то же самое, что и имя тега
  • nodeName узла атрибута — это имя атрибута
  • nodeName текстового узла — это всегда #text
  • nodeName узла документа — всегда #document

Пример


<h1 id="id01">Моя первая страница</h1>
<p id="id02"></p>

<script>
  document.getElementById("id02").innerHTML = document.getElementById("id01").nodeName;
</script>

Внимание! Свойство nodeName всегда содержит имя тега HTML элемента в верхнем регистре.

Свойство nodeValue

Свойство nodeValue определяет значение узла.

  • nodeValue для узлов элементов имеет значение null
  • nodeValue для текстовых узлов содержит сам текст
  • nodeValue для узлов атрибутов содержит значение атрибута

Свойство nodeType

Свойство nodeType имеет статус "только для чтения". Оно возвращает тип узла.

Пример


<h1 id="id01">Моя первая страница</h1>
<p id="id02"></p>

<script>
  document.getElementById("id02").innerHTML = document.getElementById("id01").nodeType;
</script>

Наиболее важные свойства nodeType:

Узел Тип Пример
ELEMENT_NODE 1 <h1 class="heading">MSiter</h1>
ATTRIBUTE_NODE 2 class = "heading" (запрещен)
TEXT_NODE 3 MSiter
COMMENT_NODE 8 <!-- Это комментарий -->
DOCUMENT_NODE 9 Сам HTML документ (родитель <html>)
DOCUMENT_TYPE_NODE 10 <!Doctype html>

Тип 2 запрещен в HTML DOM (хотя работает). Он разрешен в XML DOM.