В предыдущих разделах вы узнали, как выбирать отдельные элементы на веб-странице. Но во многих случаях вам необходим доступ к дочернему или родительскому элементу. Подробнее см. Руководство по структуре DOM JavaScript, чтобы понять логические отношения между узлами в дереве DOM.
Узел DOM предоставляет несколько свойств и методов, которые позволяют вам перемещаться по древовидной структуре DOM и очень легко вносить изменения. В этом разделе мы узнаем, как перемещаться вверх, вниз и вбок в дереве DOM с помощью JavaScript.
Доступ к дочерним узлам
Вы можете использовать свойства firstChild
и lastChild
узла DOM для доступа к первому и последнему прямому потомку элемента, соответственно. Если у узла нет дочернего элемента, он вернет null
.
<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>
<script>
var main = document.getElementById("main");
console.log(main.firstChild.nodeName); // Печатает: #text
var hint = document.getElementById("hint");
console.log(hint.firstChild.nodeName); // Печатает: SPAN
</script>
nodeName
— это свойство только для чтения, которое возвращает имя текущего узла в виде строки. Например, он возвращает имя тега для узла элемента, #text
для текстового узла, #comment
для узла комментария, #document
для узла документа и так далее.
Если вы заметили приведенный выше пример, nodeName
первого дочернего узла основного элемента <div>
возвращает #text
вместо <h1>
. Потому что такие символы, как пробелы, табуляции, переводы строк и т. д., являются допустимыми символами. Они образуют узлы #text
и становятся частью дерева DOM. Следовательно, поскольку тег <div>
содержит новую строку перед тегом <h1>
, он создаст узел #text.
Чтобы избежать проблемы с firstChild
и
, возвращающими узлы lastChild
#text
или #comment
, вы можете использовать свойства firstElementChild
и lastElementChild
, чтобы возвращать только первый и последний элемент соответственно. Но это не работает в IE 9 и более ранних версиях.
<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>
<script>
var main = document.getElementById("main");
alert(main.firstElementChild.nodeName); // Выводит: H1
main.firstElementChild.style.color = "red";
var hint = document.getElementById("hint");
alert(hint.firstElementChild.nodeName); // Выводит: SPAN
hint.firstElementChild.style.color = "blue";
</script>
Точно так же вы можете использовать свойство childNodes
для доступа ко всем дочерним узлам данного элемента, где первому дочернему узлу присвоен индекс 0
. Вот пример:
<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>
<script>
var main = document.getElementById("main");
// Сначала проверяем, что элемент имеет дочерние узлы
if(main.hasChildNodes()) {
var nodes = main.childNodes;
// Проходим по списку узлов и печатаем их имена
for(var i = 0; i < nodes.length; i++) {
alert(nodes[i].nodeName);
}
}
</script>
childNodes
возвращает все дочерние узлы, включая неэлементные узлы, такие как #text
и #comment
. Чтобы получить коллекцию только элементов, используйте вместо этого свойство children
.
<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>
<script>
var main = document.getElementById("main");
// Сначала проверяем, что элемент имеет дочерние узлы
if(main.hasChildNodes()) {
var nodes = main.children;
// Проходим по списку узлов и печатаем их имена
for(var i = 0; i < nodes.length; i++) {
alert(nodes[i].nodeName);
}
}
</script>
Доступ к родительским узлам
Вы можете использовать свойство parentNode
для доступа к родителю указанного узла в дереве DOM.
parentNode
всегда будет возвращать null
для узла документа, так как у него нет родителя.
<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>
<script>
var hint = document.getElementById("hint");
alert(hint.parentNode.nodeName); // Выводит: DIV
alert(document.documentElement.parentNode.nodeName); // Выводит: #document
alert(document.parentNode); // Выводит: null
</script>
К верхним узлам дерева DOM можно обращаться непосредственно как к свойствам document
. Например, к элементу <html>
можно получить доступ с помощью свойства document.documentElement
, тогда как к элементу <head>
можно получить доступ с помощью свойства document.head
, а к элементу <body>
можно получить доступ с помощью свойства document.body
.
Однако, если вы хотите получить только узлы элементов, вы можете использовать parentElement
, например так:
<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>
<script>
var hint = document.getElementById("hint");
alert(hint.parentNode.nodeName); // Печатаем: DIV
hint.parentNode.style.backgroundColor = "yellow";
</script>
Доступ к смежным узлам
Вы можете использовать свойства previousSibling
и nextSibling
для доступа к предыдущему и следующему узлу в дереве DOM соответственно. Вот пример:
<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p><hr>
</div>
<script>
var title = document.getElementById("title");
alert(title.previousSibling.nodeName); // Выводит: #text
var hint = document.getElementById("hint");
alert(hint.nextSibling.nodeName); // Выводит: HR
</script>
В качестве альтернативы, вы можете использовать previousElementSibling
и nextElementSibling
чтобы получить предыдущий и следующий элемент родственного элемента, пропускающий любые пробельные текстовые узлы. Все эти свойства возвращают null
, если такого элемента не существует. Вот пример:
<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>
<script>
var hint = document.getElementById("hint");
alert(hint.previousElementSibling.nodeName); // Выводит: H1
alert(hint.previousElementSibling.textContent); // Выводит: My Heading
var title = document.getElementById("title");
alert(title.nextElementSibling.nodeName); // Выводит: P
alert(title.nextElementSibling.textContent); // Выводит: This is some text.
</script>
Свойство textContent
представляет текстовое содержимое узла и всех его потомков. Подробнее см. Руководство по манипуляциям DOM в JavaScript.
Типы DOM-узлов
Дерево DOM состоит из различных типов узлов, таких как элементы, текст, комментарии и т. д.
Каждый узел имеет свойство nodeType
, которое вы можете использовать, чтобы узнать, с каким типом узла вы имеете дело. В следующей таблице перечислены наиболее важные типы узлов:
Константа | Значение | Описание |
---|---|---|
ELEMENT_NODE |
1 | Элемент узла, такой как <p> или <img> . |
TEXT_NODE |
3 | Фактический текст элемента. |
COMMENT_NODE |
8 | Узел комментария, т.е. <!-- some comment --> |
DOCUMENT_NODE |
9 | Узел документа, то есть родительский узел <html> . |
DOCUMENT_TYPE_NODE |
10 | Узел типа документа, например <!DOCTYPE html> . |