Навигация только по элементам
Навигационные свойства, описанные выше, относятся ко всем узлам в документе. В частности, в childNodes
находятся и текстовые узлы и узлы-элементы и узлы-комментарии, если они есть.
Но для большинства задач текстовые узлы и узлы-комментарии нам не нужны. Мы хотим манипулировать узлами-элементами, которые представляют собой теги и формируют структуру страницы.
Поэтому давайте рассмотрим дополнительный набор ссылок, которые учитывают только узлы-элементы:
Эти ссылки похожи на те, что раньше, только в ряде мест стоит слово Element
:
children
– коллекция детей, которые являются элементами.firstElementChild
,lastElementChild
– первый и последний дочерний элемент.previousElementSibling
,nextElementSibling
– соседи-элементы.parentElement
– родитель-элемент.
Зачем нужен parentElement
? Разве может родитель быть не элементом?
Свойство parentElement
возвращает родитель-элемент, а parentNode
возвращает «любого родителя». Обычно эти свойства одинаковы: они оба получают родителя.
За исключением document.documentElement
:
alert( document.documentElement.parentNode ); // выведет document
alert( document.documentElement.parentElement ); // выведет null
Причина в том, что родителем корневого узла document.documentElement
(<html>
) является document
. Но document
– это не узел-элемент, так что parentNode
вернёт его, а parentElement
нет.
Эта деталь может быть полезна, если мы хотим пройти вверх по цепочке родителей от произвольного элемента elem
к <html>
, но не до document
:
while(elem = elem.parentElement) { // идти наверх до <html>
alert( elem );
}
Изменим один из примеров выше: заменим childNodes
на children
. Теперь цикл выводит только элементы:
<html>
<body>
<div>Начало</div>
<ul>
<li>Информация</li>
</ul>
<div>Конец</div>
<script>
for (let elem of document.body.children) {
alert(elem); // DIV, UL, DIV, SCRIPT
}
</script>
...
</body>
</html>
Ещё немного ссылок: таблицы
До сих пор мы описывали основные навигационные ссылки.
Некоторые типы DOM-элементов предоставляют для удобства дополнительные свойства, специфичные для их типа.
Таблицы – отличный пример таких элементов.
Элемент <table>
, в дополнение к свойствам, о которых речь шла выше, поддерживает следующие:
table.rows
– коллекция строк<tr>
таблицы.table.caption/tHead/tFoot
– ссылки на элементы таблицы<caption>
,<thead>
,<tfoot>
.table.tBodies
– коллекция элементов таблицы<tbody>
(по спецификации их может быть больше одного).
<thead>
, <tfoot>
, <tbody>
предоставляют свойство rows
:
tbody.rows
– коллекция строк<tr>
секции.
<tr>
:
tr.cells
– коллекция<td>
и<th>
ячеек, находящихся внутри строки<tr>
.tr.sectionRowIndex
– номер строки<tr>
в текущей секции<thead>/<tbody>/<tfoot>
.tr.rowIndex
– номер строки<tr>
в таблице (включая все строки таблицы).
<td>
and <th>
:
td.cellIndex
– номер ячейки в строке<tr>
.
Пример использования:
<table id="table">
<tr>
<td>один</td><td>два</td>
</tr>
<tr>
<td>три</td><td>четыре</td>
</tr>
</table>
<script>
// выводит содержимое первой строки, второй ячейки
alert( table.rows[0].cells[1].innerHTML ) // "два"
</script>
Спецификация: tabular data.
Существуют также дополнительные навигационные ссылки для HTML-форм. Мы рассмотрим их позже, когда начнём работать с формами.
Итого
Получив DOM-узел, мы можем перейти к его ближайшим соседям используя навигационные ссылки.
Есть два основных набора ссылок:
- Для всех узлов:
parentNode
,childNodes
,firstChild
,lastChild
,previousSibling
,nextSibling
. - Только для узлов-элементов:
parentElement
,children
,firstElementChild
,lastElementChild
,previousElementSibling
,nextElementSibling
.
Некоторые виды DOM-элементов, например таблицы, предоставляют дополнительные ссылки и коллекции для доступа к своему содержимому.