Свойство childNodes
Свойство childNodes хранит в себе псевдомассив дочерних узлов элемента (теги, комментарии и текстовые узлы).
Синтаксис
элемент.childNodes;
Пример
Получим все дочерние узлы элемента и выведем на экран их содержимое:
текст
абзац
let parent = document.querySelector(‘#parent’); let nodes = parent.childNodes; for (let node of nodes) < console.log(node.textContent); >
Пример
Выведем содержимое первого узла:
текст
абзац
let parent = document.querySelector(‘#parent’); console.log(parent.childNodes[0].textContent);
Результат выполнения кода:
Пример
Выведем содержимое узла с номером 2 :
текст
абзац
let parent = document.querySelector(‘#parent’); console.log(parent.childNodes[2].textContent);
Результат выполнения кода:
‘ коментарий ‘
Смотрите также
- свойство children ,
которое содержит дочерние элементы - свойство firstChild ,
которое содержит первый узел - свойство lastChild ,
которое содержит последний узел
Node.childNodes
Доступный для чтения аттрибут Node.childNodes возвращает коллекцию дочерних элементов данного элемента.
Синтаксис
var ndList = elementNodeReference.childNodes;
ndList — упорядоченная коллекция объектов элементов, которые являются детьми данного элемента. Если у элемента нет детей, ndList пуст.
ndList — переменная, хранящая список дочерних элементов. Тип этого списка — NodeList .
Пример
// parg -- ссылка на элемент if (parg.hasChildNodes()) // Таким образом, сначала мы проверяем, не пуст ли объект, есть ли у него дети var children = parg.childNodes; for (var i = 0; i children.length; ++i) // сделать что-то с каждым внутренним элементом через children[i] // ПРИМЕЧАНИЕ: Список является ссылкой, Добавление или удаление дочерних элементов изменит список > >
// Это один из способов удалить все дочерние элементы из элемента // box -- ссылка на элемент с детьми while (box.firstChild) //Список является ссылкой, то есть он будет переиндексирован перед каждым вызовом box.removeChild(box.firstChild); >
Примечания
Элементы в коллекции — объекты, а не строки. Чтобы получить данные из этих объектов, вы должны использовать их свойства (например, elementNodeReference.childNodes[1].nodeName чтобы получить имя, и т. д.).
Объект document обладает 2-мя детьми: декларацией Doctype и корневым элементов, к которому как правило обращаются как documentElement . (В (X)HTML документах это HTML-элемент.)
childNodes также включают, например, текстовые узлы и комментарии. Чтобы пропустить их, используйте ParentNode.children (en-US) взамен.
Спецификации
| Specification |
|---|
| DOM Standard # ref-for-dom-node-childnodes① |
Совместимость с браузерами
BCD tables only load in the browser
Смотрите также
- Node.firstChild
- Node.lastChild
- Node.nextSibling
- Node.previousSibling
- ParentNode.children (en-US)
Found a content problem with this page?
- Edit the page on GitHub.
- Report the content issue.
- View the source on GitHub.
This page was last modified on 7 авг. 2023 г. by MDN contributors.
Your blueprint for a better internet.
Навигация по DOM-элементам
Материал на этой странице устарел, поэтому скрыт из оглавления сайта.
Более новая информация по этой теме находится на странице https://learn.javascript.ru/dom-navigation.
DOM позволяет делать что угодно с HTML-элементом и его содержимым, но для этого нужно сначала нужный элемент получить.
Доступ к DOM начинается с объекта document . Из него можно добраться до любых узлов.
Так выглядят основные ссылки, по которым можно переходить между узлами DOM:

Посмотрим на них повнимательнее.
Сверху documentElement и body
Самые верхние элементы дерева доступны напрямую из document .
= document.documentElement Первая точка входа – document.documentElement . Это свойство ссылается на DOM-объект для тега . = document.body Вторая точка входа – document.body , который соответствует тегу .
В современных браузерах (кроме IE8-) также есть document.head – прямая ссылка на
Есть одна тонкость: document.body может быть равен null
Нельзя получить доступ к элементу, которого ещё не существует в момент выполнения скрипта.
В частности, если скрипт находится в , то в нём недоступен document.body .
Поэтому в следующем примере первый alert выведет null :
В DOM активно используется null
В мире DOM в качестве значения, обозначающего «нет такого элемента» или «узел не найден», используется не undefined , а null .
Дети: childNodes, firstChild, lastChild
Здесь и далее мы будем использовать два принципиально разных термина.
- Дочерние элементы (или дети) – элементы, которые лежат непосредственно внутри данного. Например, внутри обычно лежат и .
- Потомки – все элементы, которые лежат внутри данного, вместе с их детьми, детьми их детей и так далее. То есть, всё поддерево DOM.
Псевдо-массив childNodes хранит все дочерние элементы, включая текстовые.
Пример ниже последовательно выведет дочерние элементы document.body :
Обратим внимание на маленькую деталь. Если запустить пример выше, то последним будет выведен элемент . На самом-то деле в документе есть ещё текст (обозначенный троеточием), но на момент выполнения скрипта браузер ещё до него не дошёл.
Пробельный узел будет в итоговом документе, но его ещё нет на момент выполнения скрипта.
Список детей – только для чтения!
Скажем больше – все навигационные свойства, которые перечислены в этой главе – только для чтения. Нельзя просто заменить элемент присвоением childNodes[i] = . .
Изменение DOM осуществляется другими методами, которые мы рассмотрим далее, все навигационные ссылки при этом обновляются автоматически.
Свойства firstChild и lastChild обеспечивают быстрый доступ к первому и последнему элементу.
При наличии дочерних узлов всегда верно:
elem.childNodes[0] === elem.firstChild elem.childNodes[elem.childNodes.length - 1] === elem.lastChild
Коллекции – не массивы
DOM-коллекции, такие как childNodes и другие, которые мы увидим далее, не являются JavaScript-массивами.
В них нет методов массивов, таких как forEach , map , push , pop и других.
var elems = document.documentElement.childNodes; elems.forEach(function(elem) < // нет такого метода! /* . */ >);
Именно поэтому childNodes и называют «коллекция» или «псевдомассив».
Это возможно, основных варианта два:
-
Применить метод массива через call/apply :
var elems = document.documentElement.childNodes; [].forEach.call(elems, function(elem) < alert( elem ); // HEAD, текст, BODY >);
var elems = document.documentElement.childNodes; elems = Array.prototype.slice.call(elems); // теперь elems - массив elems.forEach(function(elem) < alert( elem.tagName ); // HEAD, текст, BODY >);
Нельзя перебирать коллекцию через for..in
Ранее мы говорили, что не рекомендуется использовать для перебора массива цикл for..in .
Коллекции – наглядный пример, почему нельзя. Они похожи на массивы, но у них есть свои свойства и методы, которых в массивах нет.
К примеру, код ниже должен перебрать все дочерние элементы . Их, естественно, два: и . Максимум, три, если взять ещё и текст между ними.
Но в примере ниже alert сработает не три, а целых 5 раз!
var elems = document.documentElement.childNodes; for (var key in elems) < alert( key ); // 0, 1, 2, length, item >
Цикл for..in выведет не только ожидаемые индексы 0 , 1 , 2 , по которым лежат узлы в коллекции, но и свойство length (в коллекции оно enumerable), а также функцию item(n) – она никогда не используется, возвращает n-й элемент коллекции, проще обратиться по индексу [n] .
В реальном коде нам нужны только элементы, мы же будем работать с ними, а служебные свойства – не нужны. Поэтому желательно использовать for(var i=0; i
Соседи и родитель
Доступ к элементам слева и справа данного можно получить по ссылкам previousSibling / nextSibling .
Родитель доступен через parentNode . Если долго идти от одного элемента к другому, то рано или поздно дойдёшь до корня DOM, то есть до document.documentElement , а затем и document .
Навигация только по элементам
Навигационные ссылки, описанные выше, равно касаются всех узлов в документе. В частности, в childNodes сосуществуют и текстовые узлы и узлы-элементы и узлы-комментарии, если есть.
Но для большинства задач текстовые узлы нам не интересны.
Поэтому посмотрим на дополнительный набор ссылок, которые их не учитывают:

Эти ссылки похожи на те, что раньше, только в ряде мест стоит слово Element :
- children – только дочерние узлы-элементы, то есть соответствующие тегам.
- firstElementChild , lastElementChild – соответственно, первый и последний дети-элементы.
- previousElementSibling , nextElementSibling – соседи-элементы.
- parentElement – родитель-элемент.
Зачем parentElement ? Неужели бывают родители не-элементы?
Свойство elem.parentNode возвращает родитель элемента.
Оно всегда равно parentElement , кроме одного исключения:
alert( document.documentElement.parentNode ); // document alert( document.documentElement.parentElement ); // null
Иногда это имеет значение, если хочется перебрать всех предков и вызвать какой-то метод, а на документе его нет.
Модифицируем предыдущий пример, применив children вместо childNodes .
Теперь он будет выводить не все узлы, а только узлы-элементы:
Всегда верны равенства:
elem.firstElementChild === elem.children[0] elem.lastElementChild === elem.children[elem.children.length - 1]
В IE8- поддерживается только children
Других навигационных свойств в этих браузерах нет. Впрочем, как мы увидим далее, можно легко сделать полифил, и они, всё же, будут.
В IE8- в children присутствуют узлы-комментарии
С точки зрения стандарта это ошибка, но IE8- также включает в children узлы, соответствующие HTML-комментариям.
Это может привести к сюрпризам при использовании свойства children , поэтому HTML-комментарии либо убирают либо используют фреймворк, к примеру, jQuery, который даёт свои методы перебора и отфильтрует их.
Особые ссылки для таблиц
У конкретных элементов DOM могут быть свои дополнительные ссылки для большего удобства навигации.
Здесь мы рассмотрим таблицу, так как это важный частный случай и просто для примера.
В списке ниже выделены наиболее полезные:
- table.rows – коллекция строк TR таблицы.
- table.caption/tHead/tFoot – ссылки на элементы таблицы CAPTION , THEAD , TFOOT .
- table.tBodies – коллекция элементов таблицы TBODY , по спецификации их может быть несколько.
- tbody.rows – коллекция строк TR секции.
- tr.cells – коллекция ячеек TD/TH
- tr.sectionRowIndex – номер строки в текущей секции THEAD/TBODY
- tr.rowIndex – номер строки в таблице
- td.cellIndex – номер ячейки в строке
один два три четыре
Даже если эти свойства не нужны вам прямо сейчас, имейте их в виду на будущее, когда понадобится пройтись по таблице.
Конечно же, таблицы – не исключение.
Аналогичные полезные свойства есть у HTML-форм, они позволяют из формы получить все её элементы, а из них – в свою очередь, форму. Мы рассмотрим их позже.
Интерактивное путешествие
Для того, чтобы убедиться, что вы разобрались с навигацией по DOM-ссылкам – вашему вниманию предлагается интерактивное путешествие по DOM.
Ниже вы найдёте документ (в ифрейме), и кнопки для перехода по нему.
Изначальный элемент – . Попробуйте по ссылкам найти «информацию». Или ещё чего-нибудь.
Вы также можете открыть документ в отдельном окне и походить по нему в браузерной консоли разработчика, чтобы лучше понять разницу между показанным там DOM и реальным.
Навигация по DOM-элементам
DOM позволяет нам делать что угодно с элементами и их содержимым, но для начала нужно получить соответствующий DOM-объект.
Все операции с DOM начинаются с объекта document . Это главная «точка входа» в DOM. Из него мы можем получить доступ к любому узлу.
Так выглядят основные ссылки, по которым можно переходить между узлами DOM:
Поговорим об этом подробнее.
Сверху: documentElement и body
Самые верхние элементы дерева доступны как свойства объекта document :
= document.documentElement Самый верхний узел документа: document.documentElement . В DOM он соответствует тегу . = document.body Другой часто используемый DOM-узел – узел тега : document.body . = document.head Тег доступен как document.head .
Есть одна тонкость: document.body может быть равен null
Нельзя получить доступ к элементу, которого ещё не существует в момент выполнения скрипта.
В частности, если скрипт находится в , document.body в нём недоступен, потому что браузер его ещё не прочитал.
Поэтому, в примере ниже первый alert выведет null :
В мире DOM null означает «не существует»
В DOM значение null значит «не существует» или «нет такого узла».
Дети: childNodes, firstChild, lastChild
Здесь и далее мы будем использовать два принципиально разных термина:
- Дочерние узлы (или дети) – элементы, которые являются непосредственными детьми узла. Другими словами, элементы, которые лежат непосредственно внутри данного. Например, и являются детьми элемента .
- Потомки – все элементы, которые лежат внутри данного, включая детей, их детей и т.д.
-
(и несколько пустых текстовых узлов):
-
и вложенные в них:
(ребёнок
-
) и (ребёнок
) – в общем, все элементы поддерева.
Коллекция childNodes содержит список всех детей, включая текстовые узлы.
Пример ниже последовательно выведет детей document.body :
Обратим внимание на маленькую деталь. Если запустить пример выше, то последним будет выведен элемент . На самом деле, в документе есть ещё «какой-то HTML-код», но на момент выполнения скрипта браузер ещё до него не дошёл, поэтому скрипт не видит его.
Свойства firstChild и lastChild обеспечивают быстрый доступ к первому и последнему дочернему элементу.
Они, по сути, являются всего лишь сокращениями. Если у тега есть дочерние узлы, условие ниже всегда верно:
elem.childNodes[0] === elem.firstChild elem.childNodes[elem.childNodes.length - 1] === elem.lastChild
Для проверки наличия дочерних узлов существует также специальная функция elem.hasChildNodes() .
DOM-коллекции
Как мы уже видели, childNodes похож на массив. На самом деле это не массив, а коллекция – особый перебираемый объект-псевдомассив.
И есть два важных следствия из этого:
- Для перебора коллекции мы можем использовать for..of :
for (let node of document.body.childNodes) < alert(node); // покажет все узлы из коллекции >
Это работает, потому что коллекция является перебираемым объектом (есть требуемый для этого метод Symbol.iterator ).
- Методы массивов не будут работать, потому что коллекция – это не массив:
alert(document.body.childNodes.filter); // undefined (у коллекции нет метода filter!)
Первый пункт – это хорошо для нас. Второй – бывает неудобен, но можно пережить. Если нам хочется использовать именно методы массива, то мы можем создать настоящий массив из коллекции, используя Array.from :
alert( Array.from(document.body.childNodes).filter ); // сделали массив
DOM-коллекции – только для чтения
DOM-коллекции, и даже более – все навигационные свойства, перечисленные в этой главе, доступны только для чтения.
Мы не можем заменить один дочерний узел на другой, просто написав childNodes[i] = . .
Для изменения DOM требуются другие методы. Мы увидим их в следующей главе.
DOM-коллекции живые
Почти все DOM-коллекции, за небольшим исключением, живые. Другими словами, они отражают текущее состояние DOM.
Если мы сохраним ссылку на elem.childNodes и добавим/удалим узлы в DOM, то они появятся в сохранённой коллекции автоматически.
Не используйте цикл for..in для перебора коллекций
Коллекции перебираются циклом for..of . Некоторые начинающие разработчики пытаются использовать для этого цикл for..in .
Не делайте так. Цикл for..in перебирает все перечисляемые свойства. А у коллекций есть некоторые «лишние», редко используемые свойства, которые обычно нам не нужны:
Соседи и родитель
Соседи – это узлы, у которых один и тот же родитель.
Например, здесь и соседи:
- говорят, что – «следующий» или «правый» сосед
- также можно сказать, что «предыдущий» или «левый» сосед .
Следующий узел того же родителя (следующий сосед) – в свойстве nextSibling , а предыдущий – в previousSibling .
Родитель доступен через parentNode .
// родителем является alert( document.body.parentNode === document.documentElement ); // выведет true // после идёт alert( document.head.nextSibling ); // HTMLBodyElement // перед находится alert( document.body.previousSibling ); // HTMLHeadElement
Навигация только по элементам
Навигационные свойства, описанные выше, относятся ко всем узлам в документе. В частности, в 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 ( ) является document . Но document – это не узел-элемент, так что parentNode вернёт его, а parentElement нет.
Эта деталь может быть полезна, если мы хотим пройти вверх по цепочке родителей от произвольного элемента elem к , но не до document :
while(elem = elem.parentElement) < // идти наверх до alert( elem ); >
Изменим один из примеров выше: заменим childNodes на children . Теперь цикл выводит только элементы: