- Структура и обход документа в JavaScript
- Отношение «родитель-ребёнок»
- Соседние узлы (сиблинги, брат, сестра)
- Дополнительные свойства узлов
- Свойства, позволяющие войти в дерево
- Перемещение по узлам дерева
- Задания
- Работа с деревом значений в 1С
- Дерево значений
- Дерево значений на форме
- Заполнение дерева значений
- Обход дерева значений
- Как свернуть и развернуть дерево значений
- Как удалить строку и очистить дерево значений
- Запрос и дерево значений
- Дерево значений в таблицу значений и обратно
- Отбор в дереве значений
Структура и обход документа в JavaScript
Для того чтобы изменить свойства узла, добавить к нему новый дочерний узел (ребёнка) или удалить существующий у него дочерний узел, необходимо данный узел сначала получить, т.е. необходимо до него как-то добраться. Чтобы мы могли перемещаться по дереву, необходимо знать, как узлы взаимосвязаны между собой, т.е. какие между ними бывают отношения (связи).
Связи (отношения) между узлами в дереве рассмотрим на примере:
I LOVE 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 .
Каждый узел в дереве имеет массив childNodes , даже если у него нет дочерних узлов. В этом случае этот массив просто пустой. Получить дочерние узлы можно в виде массива childNodes и с помощью свойств firstChild (возвращает первый дочерний узел) и lastChild (возвращает последний дочерний узел).
Каждый узел в дереве имеет родительский узел, кроме узла document . Получить родительский узел можно с помощью свойства parentNode .
Соседние узлы (сиблинги, брат, сестра)
Кроме как двигаться сверху вниз и снизу вверх по дереву, JavaScript также позволяет двигаться в горизонтальном направлении между соседними узлами, т.е. узлами, которые имеют одного родителя.
В нашем примере соседними узлами являются: текстовый узел » I «, узел элемента strong и текстовый узел » JAVASCRIPT «.
Для перемещения между соседними узлами в JavaScript нам доступны следующие свойства:
- nextSibling — для перемещения слева направо, т.е. к следующему соседу (сиблингу). Если соседа справа нет, то данное свойство возвращает значение null .
- previousSibling — для перемещения справа налево, т.е. к предыдущему соседу (сиблингу). Если соседа слева нет, то данное свойство возвращает значение null .
В качестве примера рассмотрим узел, образованный элементом strong . Данный узел имеет соседа слева — текстовый узел » I » ( previousSibling ) и соседа справа — текстовый узел » JAVASCRIPT » ( nextSibling ).
Дополнительные свойства узлов
Кроме рассмотренных выше свойств в 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
Откроем консоль браузера (клавиша 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!"
Задания
- Как с помощью одной инструкции добраться от узла document до текстового узла » JAVASCRIPT «;
- Как с помощью одной инструкции добраться, наоборот, от текстового узла » JAVASCRIPT » до узла элемента head ;
- Задать узлу strong атрибут id со значением love . Написать функцию, перебирающую все узлы в дереве. Добавить в данную функцию условие: если у узла id=»love» , то изменить значение первого его дочернего узла на » VERY MUCH LOVE «. Для получения id узла используйте свойство id .
Источник
Работа с деревом значений в 1С
В последнее время аномально часто мне в работе попадалось дерево значений, поэтому решил написать на эту тему статью.
Попробую рассмотреть способы решения основных задач связанных с деревом значений, при этом постараюсь писать «без воды».
Дерево значений
Из названия объекта понятно, что дерево значений служит для хранения/отображения какой-либо иерархической информации. Каждая строка дерева значений может иметь какое-то количество подчиненных строк, при этом такие операции как поиск, сортировка, подсчет итогов можно проводит с учетом уровня иерархии и подчиненных строк.
Кроме этого, каждая строка дерева значений имеет свойства «Родитель» и «Строки».
Дерево значений на форме
Визуальное представление дерева значений обеспечивает элемент «Табличное поле».
Заполнение дерева значений
При заполнении дерева значений нужно помнить, что сам объект «ДеревоЗначений» и все его строки имеют свойство «Строки»и добавление новых строк на любом уровне дерева осуществляется через это свойство.
Сам же объект «ДеревоЗначений» имеет еще и свойство «Колонки», которое ничем не отличается от аналогичного свойства у таблицы значений.
Небольшой пример программного заполнения таблицы значений для управляемых форм:
Обход дерева значений
Обход всех строк дерева значений делается при помощи рекурсии, вот так будет выглядеть код для обхода дерева созданного в примере выше:
Как свернуть и развернуть дерево значений
Сворачивается и разворачивается дерево значений очень просто.
Привел три примера: для сворачивания текущей строки, для сворачивания строк верхнего уровня, для сворачивания вообще всех строк (рекурсия).
Два примера: для разворачивания текущей строки и для разворачивания всех строк. У метода «Развернуть» есть дополнительный параметр, который позволяет указать нужно ли разворачивать подчиненные строки.
Как удалить строку и очистить дерево значений
Тут опять же все просто, нужно помнить, что при удалении/очистке строки, все подчиненные строки удаляются.
Точно также можно очистить от подчиненных элементов другую другую строку.
Удалить строку дерева значений не сложнее — нужно только знать ее индекс:
Запрос и дерево значений
Результат выполнения запроса очень легко преобразовать в дерево значений, для этого нужно воспользоваться методом «Выгрузить» и указать параметр «ТипОбхода» отличным от того, что стоит по умолчанию, т.е. «ПоГруппировкам» или «ПоГруппировкамСИерархией».
Если на форме имеется реквизит «ДеревоЗначений» и связанный с ним визуальный элемент, то можно сделать примерно так:
Причем полного совпадения колонок и типов не требуется — лишние колонки будут просто отброшены, а колонки с различными типами будут заполнены пустыми значениями.
Дерево значений в таблицу значений и обратно
Преобразовать дерево значений в таблицу значений и наоборот достаточно просто, ведь дерево значений это та же таблица значений, но с дополнительной колонкой — «Родитель». У меня есть отдельная статья о том как преобразовать дерево значений в таблицу значений и обратно.
Отбор в дереве значений
Стандартного отбора в дереве значений не предусмотрено. Так получилось потому, что непонятно как разрешать ситуацию, когда родительский элемент не удовлетворяет условию отбора, а подчиненные ему элементы удовлетворяют.
Таким образом, если Вам нужно реализовать отбор в дереве значений, то начать нужно с решения именно этой проблемы. А уже после этого можно придумать несколько способов реализовать задуманное.
Первый способ — накладывать отбор до вывода дерева значений (в запросе например). Это не классический отбор, но в тех случаях когда этот способ применим, то следует применять именно его, так как это почти всегда быстрее и правильнее чем что-либо другое.
Второй способ — перебор всех строк дерева значений. Описывать здесь особенно нечего, нужно просто взять обход дерева значений, проверять каждую строку на соответствие условию отбора и удалять лишние строки.
Еще один способ заключается в том, чтобы преобразовать дерево значений в таблицу значений, сделать отбор в таблице значений, проконтролировать результат (почистить «хвосты» — строки, родитель которых не удовлетворил условию отбора) и выполнить обратное преобразование в дерево значений.
На этом все, рассказал все, что знал, надеюсь мне удалось сэкономить Вам немного времени.
Если Вы нашли ошибку или неточность, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.
(оценок: 36, средняя оценка: 4,64 из 5)
Источник