Структура и обход документа в JavaScript
На этом уроке мы рассмотрим, какие связи (отношения) существуют между узлами в дереве, а также с помощью каких свойств они описываются.
Связи (отношения) между узлами
Для того чтобы изменить свойства узла, добавить к нему новый дочерний узел (ребёнка) или удалить существующий у него дочерний узел, необходимо данный узел сначала получить, т.е. необходимо до него как-то добраться. Чтобы мы могли перемещаться по дереву, необходимо знать, как узлы взаимосвязаны между собой, т.е. какие между ними бывают отношения (связи).
Связи (отношения) между узлами в дереве рассмотрим на примере:
<p>I <strong>LOVE</strong> JAVASCRIPT</p>

Отношение "родитель-ребёнок"
В нашем примере узел р
является родительским узлом для:
- Узлов, образованных на основе текста: " I" и " JAVASCRIPT".
- Узла, образованным элементом
strong
.
Следовательно, у узла р
в массиве childNodes
будет 3 узла.
//узелP - переменная, хранящая ссылку на узел p
узелP.childNodes[0]; //1 дочерний узел (ребёнок) #text "I "
узелP.childNodes[1]; //2 дочерний узел (ребёнок) strong
узелP.childNodes[2]; //3 дочерний узел( ребёнок) #text " JAVASCRIPT"
Для того чтобы обратиться к первому или последнему элементу массива childNodes
в JavaScript доступны следующие свойства: firstChild
(первый элемент в массиве childNodes
) и lastChild
(последний элемент в массиве childNodes
).
С помощью этих свойств (childNodes
, firstChild
, lastChild
) Вы можете перемещаться по дереву сверху вниз, т.е. от родительского узла к дочернему.
Кроме этого, каждый узел в дереве имеет родительский узел, обратиться к которому можно с помощью свойства parentNode
. Используя данное свойство Вы можете подниматься по дереву, т.е. перемещаться от дочернего узла к родительскому.
Например, рассмотрим узел, образованный с помощью элемента strong
. Для него родительским узлом является узел р
, который можно получить через свойство parentNode
узла strong
. Кроме родительского узла, у узла strong
есть один дочерний узел, который является текстовым и имеет значение "LOVE
". Получить дочерние узлы у узла p
можно в виде массива childNodes
и с помощью свойств firstChild
и lastChild
.

Каждый узел в дереве имеет массив childNodes
, даже если у него нет дочерних узлов. В этом случае этот массив просто пустой. Получить дочерние узлы можно в виде массива childNodes
и с помощью свойств firstChild
(возвращает первый дочерний узел) и lastChild
(возвращает последний дочерний узел).
Каждый узел в дереве имеет родительский узел, кроме узла document
. Получить родительский узел можно с помощью свойства parentNode
.
Соседние узлы (сиблинги, брат, сестра)
Кроме как двигаться сверху вниз и снизу вверх по дереву, JavaScript также позволяет двигаться в горизонтальном направлении между соседними узлами, т.е. узлами, которые имеют одного родителя.
В нашем примере соседними узлами являются: текстовый узел "I
", узел элемента strong
и текстовый узел " JAVASCRIPT
".
Для перемещения между соседними узлами в JavaScript нам доступны следующие свойства:
nextSibling
- для перемещения слева направо, т.е. к следующему соседу (сиблингу). Если соседа справа нет, то данное свойство возвращает значениеnull
.previousSibling
- для перемещения справа налево, т.е. к предыдущему соседу (сиблингу). Если соседа слева нет, то данное свойство возвращает значениеnull
.
В качестве примера рассмотрим узел, образованный элементом strong
. Данный узел имеет соседа слева - текстовый узел "I
" (previousSibling
) и соседа справа - текстовый узел " JAVASCRIPT
" (nextSibling
).

Дополнительные свойства узлов
Кроме рассмотренных выше свойств в JavaScript есть дополнительные свойства, с помощью которых вы можете перемещаться по узлам дерева, образованными элементами:
children
(возвращает коллекцию дочерних элементов (детей));firstElementChild
(возвращает первый дочерний узел-элемент);lastElementChild
(возвращает последний дочерний узел-элемент);parentElement
(родительский узел-элемент);nextElementSibling
(следующий соседний узел-элемент);previousElementSibling
(предыдущий соседний узел-элемент).
Свойства, позволяющие войти в дерево
Но перед тем как начать перемещаться по узлам дерева нам в него необходимо как-то попасть. Войти в DOM можно с помощью document.childNodes[0]
, document.firstChild
, document.lastChild
, document.documentElement
и document.body
.
- Свойство
document.documentElement
- возвращает элемент документа, который является корневым. В HTML документах корневым элементом является элементhtml
. Данное свойство доступно только для чтения. - Свойство
document.body
- возвращает узелbody
текущего документа илиnull
, если такой элемент не существует.
Перемещение по узлам дерева
В качестве примера рассмотрим ранее приведённый код, который дополним основными элементами HTML документа. Весь код запишем без переносов строк и табуляции для того чтобы в дереве не было лишних текстовых узлов:
<html><head></head><body><p>I <strong>LOVE</strong> JAVASCRIPT</p></body></html>

Откроем консоль браузера (клавиша F12, вкладка "Консоль") и "прогуляемся" по дереву документа:
nodeHtml = document.documentElement //html
nodeBody = nodeHtml.lastChild //body
nodeP = nodeBody.childNodes[0] //p
nodeP.nodeValue //null
nodeP.nodeType //1
nodeP.nodeName //p
nodeText1 = nodeP.firstChild //#text "I "
nodeStrong = nodeText1.nextSibling //strong
nodeText2 = nodeStrong.firstChild //#text "LOVE"
nodeStrong = nodeText2.parentNode //strong
nodeText3 = nodeStrong.nextSibling //#text " JAVASCRIPT"
nodeText3.nodeValue //" JAVASCRIPT"
nodeText3.nodeType //3
nodeText3.nodeName //#text
nodeText3.nodeValue = " HTML, CSS AND JAVASCRIPT!"; //#text " HTML, CSS AND JAVASCRIPT!"

Задания
- Как с помощью одной инструкции добраться от узла
document
до текстового узла "JAVASCRIPT
"; - Как с помощью одной инструкции добраться, наоборот, от текстового узла "
JAVASCRIPT
" до узла элементаhead
; - Задать узлу
strong
атрибутid
со значениемlove
. Написать функцию, перебирающую все узлы в дереве. Добавить в данную функцию условие: если у узлаid="love"
, то изменить значение первого его дочернего узла на "VERY MUCH LOVE
". Для полученияid
узла используйте свойствоid
.