DOM, часть 1 из 3. Навигация по элементам

02.06.2021

Теги: DOMFrontendHTMLJavaScriptWeb-разработкаДокументКоллекцияТеория

В соответствии с объектной моделью документа («Document Object Model», коротко DOM), каждый HTML-тег является объектом. Вложенные теги являются «детьми» родительского элемента. Текст, который находится внутри тега, также является объектом.

Все операции с DOM начинаются с объекта document, это главная «точка входа» в DOM. Из него можно получить доступ к любому узлу документа.

Сверху: documentElement и body

Самый верхний узел документа — document.documentElement, в DOM он соответствует тегу <html>:

<html> = document.documentElement

Другой часто используемый DOM-узел — document.body, в DOM он соответствует тегу <body>:

<body> = document.body
Нельзя получить доступ к элементу, которого ещё не существует в момент выполнения скрипта. В частности, если скрипт находится в <head>, то document.body в нём недоступен, потому что браузер его ещё не прочитал.

Дети: childNodes, firstChild, lastChild

Надо понимать разницу между понятиями «дети» и «потомки». Дети (дочерние узлы) — элементы, которые являются непосредственными детьми узла. Потомки — все элементы, которые лежат внутри данного, включая детей, их детей и т.д.

  • Коллекция childNodes содержит список всех детей, включая текстовые узлы.
  • Свойства firstChild и lastChild обеспечивают доступ к первому и последнему дочернему узлу.
Для проверки наличия дочерних узлов существует специальная функция element.hasChildNodes().

Коллекция childNodes

Хотя childNodes имеет свойство length — это не массив, а особый перебираемый объект NodeList.

for (let node of document.body.childNodes) {
    alert(node); // покажет все узлы из коллекции
}

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

let children = Array.from(document.body.childNodes);

Методы NodeList

NodeList.item(index). Возвращает элемент из списка по его индексу или null, если индекс выходит за границы допустимого диапазона. Может быть использован как альтернатива nodeList[index], возвращающему undefined при недопустимом index.

NodeList.entries(). Возвращает iterator, позволяя перебрать все пары ключ/значение, содержащиеся в NodeList.

NodeList.forEach(). Выполняет указанную функцию один раз для каждого элемента NodeList.

NodeList.keys(). Возвращает iterator, позволяя перебрать все ключи каждой пары ключ/значение, содержащейся в NodeList.

NodeList.values(). Возвращает iterator, позволяя перебрать все значения каждой пары ключ/значение, содержащейся в NodeList.

Соседи и родитель

Соседи — это узлы, у которых один и тот же родитель. Свойства nextSibling и previousSibling обеспечивают доступ к следующему и предыдущему узлу. Родитель доступен через свойство parentNode.

Навигация только по элементам

Навигационные свойства, описанные выше, относятся ко всем узлам в документе. В частности, в 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 — нет.

Эта деталь может быть полезна, если нужно пройти вверх по цепочке родителей от произвольного элемента element к <html>, но не до document.

while(element = element.parentElement) { // идти наверх до <html>
    alert( element );
}

Коллекция children

Хотя children имеет свойство length — это не массив, а особый перебираемый объект HTMLCollection.

for (let node of document.body.children) {
    alert(node); // покажет все элементы коллекции
}

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

let children = Array.from(document.body.children);

Методы HTMLCollection

HTMLCollection.item(index). Возвращает узел с порядковым номером index, отсчёт ведётся от нуля. Возвращает null, если index выходит за границы допустимого диапазона.

HTMLCollection.namedItem(name). Возвращает узел, идентификатор или имя (в целях совместимости) которого совпадает со строкой, переданной в аргументе. Соответствие имени проверяется в самую последнюю очередь, только для HTML-элементов и только для тех из них, которые поддерживают свойство name. Возвращает null, если искомый элемент отсутствует.

Поиск: DOM • JavaScript • Web-разработка • Теория • Узел • document

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.