Чем является childnodes в elem childnodes
Перейти к содержимому

Чем является childnodes в elem childnodes

Навигация по 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 похож на массив. На самом деле это не массив, а коллекция – особый перебираемый объект-псевдомассив.

    И есть два важных следствия из этого:

    1. Для перебора коллекции мы можем использовать for..of :
    for (let node of document.body.childNodes) < alert(node); // покажет все узлы из коллекции >

    Это работает, потому что коллекция является перебираемым объектом (есть требуемый для этого метод Symbol.iterator ).

    1. Методы массивов не будут работать, потому что коллекция – это не массив:
    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 . Теперь цикл выводит только элементы:

    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.

    Свойство 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 ,
      которое содержит последний узел

    Навигация по DOM-дереву — JS: DOM API

    Знакомство с DOM-деревом проще всего начать с изучения структуры этого дерева.

    Если коротко, DOM-дерево состоит из узлов (нод, node). Вместе узлы образуют иерархию, аналогичную HTML. При этом узлы делятся на два типа:

    • Листовые — не содержат внутри себя других узлов
    • Внутренние – у них есть узлы

    Чаще всего конкретные узлы описывают конкретные теги из HTML и содержат их атрибуты внутри себя. У узлов есть тип, который определяет набор свойств и методов узла. В этом уроке мы с ними познакомимся.

    Корневой элемент в DOM-дереве соответствует тегу . Доступ к нему можно получить так:

    const html = document.documentElement; // Свойство tagName узла содержит имя тега в верхнем регистре console.log(html.tagName); // => 'HTML' // Содержимое тега HTML в виде узлов DOM-дерева // Текст тоже представлен узлом html.childNodes; // [head, text, body] // Потому что head выше body html.firstChild; // .  html.lastChild; // .  // Второй узел, обращение по индексу html.childNodes[1]; // #text 

    Теги и всегда присутствуют внутри документа, поэтому можно вынести их на уровень объекта document для более простого доступа:

    document.head; document.body; 

    По дереву можно не только спускаться, но и подниматься:

    // Родитель body это html document.documentElement === document.body.parentNode; // true document.body === document.body.childNodes[2].parentNode; // true 

    Если представить дерево, то по нему можно двигаться как вверх-вниз, так и влево-вправо. Картинка ниже это демонстрирует:

    childNodes

    Далее мы рассмотрим childNodes – свойство, с помощью которого можно получить дочерние узлы — это узлы, вложенные в текущий узел на один уровень вложенности. Еще говорят, что это потомки первого уровня.

    В работе с childNodes есть несколько интересных моментов:

      Это свойство доступно только для чтения. Попытка что-то записать в конкретный элемент не приведет к успеху:

    // Ошибки не будет, но ничего не поменяется document.body.childNodes[0] = 'hey'; 
    // Тип NodeList const nodes = document.documentElement.childNodes; nodes.forEach((el) => console.log(el)); 

    Если очень хочется, то его можно преобразовать в массив, и затем уже работать привычным способом:

    const list = Array.from(nodes); // Теперь у нас обычный массив и доступные методы, например, filter // Можем отфильтровать нужные элементы const filtered = list.filter((item) => item.textContent.includes('Навигация по DOM-дереву')); // И извлечь из них данные, например, имена тегов const filteredTags = filtered.map((item) => item.tagName); console.log(filteredTags); // => ['HEAD', 'BODY'] 

    Иерархия

    Узлы DOM-дерева не просто так делятся на типы. Эти типы выстраиваются в иерархию от общего к частному. В иерархии подтипы наследуют свойства и методы родительских типов и добавляют свои:

    // Самый простой способ посмотреть тип document.body.toString(); // "[object HTMLBodyElement]" document.body instanceof HTMLBodyElement; // true 

    Узлы с типами Text и Comment являются листовыми, то есть они не могут иметь потомков. А вот элементы или производные типы от Element — это то, с чем приходится иметь дело чаще всего. К элементам относятся все типы, представленные тегами в HTML.

    При работе с деревом естественным образом возникает понятие потомки. Применительно к DOM-дереву это означает, что тег с содержимым имеет потомков.

    Посмотрите на пример кода:

    В этом примере тег (с id parent-div ) содержит 14 потомков, в том числе три дочерних узла. Разберемся, в чем разница между этими понятиями.

    Дочерними называют только те узлы, которые находятся на первом уровне вложенности. То есть дочерними будут считаться:

    • Текст «Привет!»
    • с классом child-div

    Потомками называют все вложенные узлы на всех уровнях вложенности. Потомками тега (с id parent-div ) будут не только три вышеупомянутых дочерних тега, но и все узлы внутри них:

    Дочерние узлы одновременно являются потомками. Обратное утверждение неверно — потомок необязательно является дочерним элементом. В нашем примере тег приходится потомком, но не дочерним элементом по отношению к тегу с id parent-div .

    Элементы

    На практике чаще всего нас интересуют не любые узлы, а элементы. Именно ими мы манипулируем, перемещаемся сквозь них. Это настолько важно, что в DOM есть альтернативный способ обхода дерева, который построен только на элементах:

    Все эти свойства возвращают объекты типа Element и пропускают объекты Text или Comment. Это видно в примере ниже, где свойство children возвращает только теги.

    Этим children отличается от childNodes , который возвращает все узлы, включая листовые:

    const node = document.documentElement; node.children; // [head, body] 

    Между children и childNodes есть еще одно довольно важное отличие. Они возвращают не только разный набор узлов, но и сам тип коллекции в первом и втором случае разный:

    • childNodes возвращает NodeList
    • children — HTMLCollection

    Они немного по-разному работают, но рассматривать эту разницу мы будем позже, когда познакомимся с селекторами.

    Специальная навигация

    Некоторые элементы обладают специальными свойствами для навигации по ним, к таким элементам относятся, например, формы и таблицы:

       1.1 1.2 1.3   2.1 2.2 2.3   
    const table = document.body.firstElementChild table.rows[0].cells[2]; 

    Этот способ навигации не заменяет основные способы. Он сделан исключительно для удобства в тех местах, где это имеет смысл.

    Заключение

    Открыть доступ

    Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

    • 130 курсов, 2000+ часов теории
    • 1000 практических заданий в браузере
    • 360 000 студентов

    Наши выпускники работают в компаниях:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *