Обход всего дерева документа

Структура и обход документа в JavaScript

Для того чтобы изменить свойства узла, добавить к нему новый дочерний узел (ребёнка) или удалить существующий у него дочерний узел, необходимо данный узел сначала получить, т.е. необходимо до него как-то добраться. Чтобы мы могли перемещаться по дереву, необходимо знать, как узлы взаимосвязаны между собой, т.е. какие между ними бывают отношения (связи).

Связи (отношения) между узлами в дереве рассмотрим на примере:

I LOVE JAVASCRIPT

JavaScript - отношения между узлами

Отношение «родитель-ребёнок»

В нашем примере узел р является родительским узлом для:

  • Узлов, образованных на основе текста: » I» и » JAVASCRIPT».
  • Узла, образованным элементом strong .

Следовательно, у узла р в массиве childNodes будет 3 узла.

//узелP - переменная, хранящая ссылку на узел p узелP.childNodes[0]; //1 дочерний узел (ребёнок) #text "I " узелP.childNodes[1]; //2 дочерний узел (ребёнок) strong узелP.childNodes[2]; //3 дочерний узел( ребёнок) #text " JAVASCRIPT"

Для того чтобы обратиться к первому или последнему элементу массива childNodes в JavaScript доступны следующие свойства: firstChild (первый элемент в массиве childNodes ) и lastChild (последний элемент в массиве childNodes ).

С помощью этих свойств ( childNodes , firstChild , lastChild ) Вы можете перемещаться по дереву сверху вниз, т.е. от родительского узла к дочернему.

Кроме этого, каждый узел в дереве имеет родительский узел, обратиться к которому можно с помощью свойства parentNode . Используя данное свойство Вы можете подниматься по дереву, т.е. перемещаться от дочернего узла к родительскому.

Например, рассмотрим узел, образованный с помощью элемента strong . Для него родительским узлом является узел р , который можно получить через свойство parentNode узла strong . Кроме родительского узла, у узла strong есть один дочерний узел, который является текстовым и имеет значение » LOVE «. Получить дочерние узлы у узла p можно в виде массива childNodes и с помощью свойств firstChild и lastChild .

JavaScript - DOM: родительский и дочерние узлы у узла strong

Каждый узел в дереве имеет массив childNodes , даже если у него нет дочерних узлов. В этом случае этот массив просто пустой. Получить дочерние узлы можно в виде массива childNodes и с помощью свойств firstChild (возвращает первый дочерний узел) и lastChild (возвращает последний дочерний узел).

Читайте также:  Ветки дерева мешают проводам

Каждый узел в дереве имеет родительский узел, кроме узла document . Получить родительский узел можно с помощью свойства parentNode .

Соседние узлы (сиблинги, брат, сестра)

Кроме как двигаться сверху вниз и снизу вверх по дереву, JavaScript также позволяет двигаться в горизонтальном направлении между соседними узлами, т.е. узлами, которые имеют одного родителя.

В нашем примере соседними узлами являются: текстовый узел » I «, узел элемента strong и текстовый узел » JAVASCRIPT «.

Для перемещения между соседними узлами в JavaScript нам доступны следующие свойства:

  • nextSibling — для перемещения слева направо, т.е. к следующему соседу (сиблингу). Если соседа справа нет, то данное свойство возвращает значение null .
  • previousSibling — для перемещения справа налево, т.е. к предыдущему соседу (сиблингу). Если соседа слева нет, то данное свойство возвращает значение null .

В качестве примера рассмотрим узел, образованный элементом strong . Данный узел имеет соседа слева — текстовый узел » I » ( previousSibling ) и соседа справа — текстовый узел » JAVASCRIPT » ( nextSibling ).

JavaScript - DOM: свойства nextSibling и previousSibling

Дополнительные свойства узлов

Кроме рассмотренных выше свойств в JavaScript есть дополнительные свойства, с помощью которых вы можете перемещаться по узлам дерева, образованными элементами:

  • children (возвращает коллекцию дочерних элементов (детей));
  • firstElementChild (возвращает первый дочерний узел-элемент);
  • lastElementChild (возвращает последний дочерний узел-элемент);
  • parentElement (родительский узел-элемент);
  • nextElementSibling (следующий соседний узел-элемент);
  • previousElementSibling (предыдущий соседний узел-элемент).

Свойства, позволяющие войти в дерево

Но перед тем как начать перемещаться по узлам дерева нам в него необходимо как-то попасть. Войти в DOM можно с помощью document.childNodes[0] , document.firstChild , document.lastChild , document.documentElement и document.body .

  • Свойство document.documentElement — возвращает элемент документа, который является корневым. В HTML документах корневым элементом является элемент html . Данное свойство доступно только для чтения.
  • Свойство document.body — возвращает узел body текущего документа или null , если такой элемент не существует.

Перемещение по узлам дерева

В качестве примера рассмотрим ранее приведённый код, который дополним основными элементами HTML документа. Весь код запишем без переносов строк и табуляции для того чтобы в дереве не было лишних текстовых узлов:

 

I LOVE JAVASCRIPT

JavaScript - дерево узлов документа

Откроем консоль браузера (клавиша F12 , вкладка «Консоль») и «прогуляемся» по дереву документа:

nodeHtml = document.documentElement //html nodeBody = nodeHtml.lastChild //body nodeP = nodeBody.childNodes[0] //p nodeP.nodeValue //null nodeP.nodeType //1 nodeP.nodeName //p nodeText1 = nodeP.firstChild //#text "I " nodeStrong = nodeText1.nextSibling //strong nodeText2 = nodeStrong.firstChild //#text "LOVE" nodeStrong = nodeText2.parentNode //strong nodeText3 = nodeStrong.nextSibling //#text " JAVASCRIPT" nodeText3.nodeValue //" JAVASCRIPT" nodeText3.nodeType //3 nodeText3.nodeName //#text nodeText3.nodeValue = " HTML, CSS AND JAVASCRIPT!"; //#text " HTML, CSS AND JAVASCRIPT!"

JavaScript - перемещения по дереву узлов документа

Задания

  1. Как с помощью одной инструкции добраться от узла document до текстового узла » JAVASCRIPT «;
  2. Как с помощью одной инструкции добраться, наоборот, от текстового узла » JAVASCRIPT » до узла элемента head ;
  3. Задать узлу strong атрибут id со значением love . Написать функцию, перебирающую все узлы в дереве. Добавить в данную функцию условие: если у узла id=»love» , то изменить значение первого его дочернего узла на » VERY MUCH LOVE «. Для получения id узла используйте свойство id .
Читайте также:  Орех дерево корпус гитары

Источник

Работа с деревом значений в 1С

В последнее время аномально часто мне в работе попадалось дерево значений, поэтому решил написать на эту тему статью.

Попробую рассмотреть способы решения основных задач связанных с деревом значений, при этом постараюсь писать «без воды».

Дерево значений

Из названия объекта понятно, что дерево значений служит для хранения/отображения какой-либо иерархической информации. Каждая строка дерева значений может иметь какое-то количество подчиненных строк, при этом такие операции как поиск, сортировка, подсчет итогов можно проводит с учетом уровня иерархии и подчиненных строк.

Кроме этого, каждая строка дерева значений имеет свойства «Родитель» и «Строки».

Дерево значений на форме

Визуальное представление дерева значений обеспечивает элемент «Табличное поле».

Дерево значений на обычной форме Дерево значений на управляемой форме

Заполнение дерева значений

При заполнении дерева значений нужно помнить, что сам объект «ДеревоЗначений» и все его строки имеют свойство «Строки»и добавление новых строк на любом уровне дерева осуществляется через это свойство.

Сам же объект «ДеревоЗначений» имеет еще и свойство «Колонки», которое ничем не отличается от аналогичного свойства у таблицы значений.

Небольшой пример программного заполнения таблицы значений для управляемых форм:

Обход дерева значений

Обход всех строк дерева значений делается при помощи рекурсии, вот так будет выглядеть код для обхода дерева созданного в примере выше:

Как свернуть и развернуть дерево значений

Сворачивается и разворачивается дерево значений очень просто.

Привел три примера: для сворачивания текущей строки, для сворачивания строк верхнего уровня, для сворачивания вообще всех строк (рекурсия).

Два примера: для разворачивания текущей строки и для разворачивания всех строк. У метода «Развернуть» есть дополнительный параметр, который позволяет указать нужно ли разворачивать подчиненные строки.

Как удалить строку и очистить дерево значений

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

Читайте также:  Чайное дерево масло при целлюлите

Точно также можно очистить от подчиненных элементов другую другую строку.

Удалить строку дерева значений не сложнее — нужно только знать ее индекс:

Запрос и дерево значений

Результат выполнения запроса очень легко преобразовать в дерево значений, для этого нужно воспользоваться методом «Выгрузить» и указать параметр «ТипОбхода» отличным от того, что стоит по умолчанию, т.е. «ПоГруппировкам» или «ПоГруппировкамСИерархией».

Если на форме имеется реквизит «ДеревоЗначений» и связанный с ним визуальный элемент, то можно сделать примерно так:

Причем полного совпадения колонок и типов не требуется — лишние колонки будут просто отброшены, а колонки с различными типами будут заполнены пустыми значениями.

Дерево значений в таблицу значений и обратно

Преобразовать дерево значений в таблицу значений и наоборот достаточно просто, ведь дерево значений это та же таблица значений, но с дополнительной колонкой — «Родитель». У меня есть отдельная статья о том как преобразовать дерево значений в таблицу значений и обратно.

Отбор в дереве значений

Стандартного отбора в дереве значений не предусмотрено. Так получилось потому, что непонятно как разрешать ситуацию, когда родительский элемент не удовлетворяет условию отбора, а подчиненные ему элементы удовлетворяют.

Таким образом, если Вам нужно реализовать отбор в дереве значений, то начать нужно с решения именно этой проблемы. А уже после этого можно придумать несколько способов реализовать задуманное.

Первый способ — накладывать отбор до вывода дерева значений (в запросе например). Это не классический отбор, но в тех случаях когда этот способ применим, то следует применять именно его, так как это почти всегда быстрее и правильнее чем что-либо другое.

Второй способ — перебор всех строк дерева значений. Описывать здесь особенно нечего, нужно просто взять обход дерева значений, проверять каждую строку на соответствие условию отбора и удалять лишние строки.

Еще один способ заключается в том, чтобы преобразовать дерево значений в таблицу значений, сделать отбор в таблице значений, проконтролировать результат (почистить «хвосты» — строки, родитель которых не удовлетворил условию отбора) и выполнить обратное преобразование в дерево значений.

На этом все, рассказал все, что знал, надеюсь мне удалось сэкономить Вам немного времени.

Если Вы нашли ошибку или неточность, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

УжасноПлохоНеплохоХорошо Отлично(оценок: 36, средняя оценка: 4,64 из 5)

Источник

Оцените статью