Как пройти DOM

Вступление

Предыдущий учебник в этой серии, How для доступа к элементам в DOM, описывает, как использовать встроенные -в методах объекта + document + для доступа к элементам HTML по идентификатору, классу, имени тега и селекторам запросов. Мы знаем, что DOM структурирован как tree узлов с узлом + document + в корне и каждый второй узел (включая элементы, комментарии и текстовые узлы) в качестве различных ветвей.

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

В этом уроке мы расскажем, как пройти через DOM (также известный как ходьба или навигация по DOM) со свойствами parent, child и sibling.

Настроить

Для начала мы создадим новый файл с именем + node.html +, состоящий из следующего кода.

nodes.html

<!DOCTYPE html>
<html>

<head>
 <title>Learning About Nodes</title>

 <style>
   * { border: 2px solid #dedede; padding: 15px; margin: 15px; }
   html { margin: 0; padding: 0; }
   body { max-width: 600px; font-family: sans-serif; color: #333; }
 </style>
</head>

<body>
 <h1>Shark World</h1>
 <p>The world's leading source on <strong>shark</strong> related information.</p>
 <h2>Types of Sharks</h2>
 <ul>
   <li>Hammerhead</li>
   <li>Tiger</li>
   <li>Great White</li>
 </ul>
</body>

<script>
 const h1 = document.getElementsByTagName('h1')[0];
 const p = document.getElementsByTagName('p')[0];
 const ul = document.getElementsByTagName('ul')[0];
</script>

</html>

Когда мы загружаем файл в веб-браузер, мы видим рендеринг, похожий на следующий скриншот.

изображение: https: //assets.digitalocean.com/articles/eng_javascript/dom/nodes-before-modification.png [node.html page]

В этом примере веб-сайта у нас есть HTML-документ с несколькими элементами. Некоторые базовые CSS были добавлены в тег + style +, чтобы сделать каждый элемент явно видимым, а в + script + было создано несколько переменных для облегчения доступа к нескольким элементам. Поскольку существует только один из каждого + h1 +, + p + и + ul +, мы можем получить доступ к первому индексу в каждом соответствующем свойстве + getElementsByTagName +.

Корневые узлы

Объект + document является корнем каждого узла в DOM. Этот объект фактически является свойством объекта + window, который является глобальным объектом верхнего уровня, представляющим вкладку в браузере. Объект https://developer.mozilla.org/en-US/docs/Web/API/Window [+ window +] имеет доступ к такой информации, как панель инструментов, высота и ширина окна, приглашения и оповещения. «+ Документ» состоит из того, что находится внутри внутреннего «+ окна».

Ниже приведена диаграмма, состоящая из корневых элементов, которые будут содержаться в каждом документе. Даже если в браузер загружен пустой HTML-файл, эти три узла будут добавлены и проанализированы в DOM.

Property Node Node Type

document

#document

DOCUMENT_NODE

document.documentElement

html

ELEMENT_NODE

document.head

head

ELEMENT_NODE

document.body

body

ELEMENT_NODE

Поскольку элементы + html,` + head` и + body + очень распространены, они имеют свои собственные свойства в + document.

Откройте Console в DevTools и протестируйте каждое из этих четырех свойств, отправив их и просмотрев выходные данные. Вы также можете проверить + h1 +, + p + и + ul +, которые будут возвращать элементы из-за переменных, которые мы добавили в тег + script +.

Родительские узлы

Узлы в DOM называются родителями, детьми и братьями и сестрами, в зависимости от их отношения к другим узлам. * Parent * любого узла - это узел, который находится на один уровень выше него или ближе к + document + в иерархии DOM. Есть два свойства для получения родителя - + parentNode + и + parentElement +.

Property Gets

parentNode

Parent Node

parentElement

Parent Element Node

В нашем примере + node.html:

  • + html является родителем` + head`, + body и` + script & `.

  • + body + является родителем для + h1 +, + h2 +, + p + и + ul +, но не + li +, поскольку + li + на два уровня ниже + body +.

Мы можем проверить, что является родителем нашего элемента + p +, с помощью свойства + parentNode +. Эта переменная + p + взята из нашего пользовательского объявления + document.getElementsByTagName ('p') [0] +.

p.parentNode;
Output► <body>...</body>

Родителем + p + является + body +, но как мы можем получить прародителя, который на два уровня выше? Мы можем сделать это, связав свойства вместе.

p.parentNode.parentNode;
Output► <html>...</html>

Используя + parentNode + дважды, мы получили прародителя + p +.

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

// Assign html object to html variable
const html = document.documentElement;

console.log(html.parentNode); // > #document
console.log(html.parentElement); // > null

Родителем практически любого узла является узел элемента, поскольку текст и комментарии не могут быть родителями для других узлов. Однако родительский элемент + html является узлом документа, поэтому` + parentElement` возвращает + null i. Обычно + parentNode + чаще используется при обходе DOM.

Детские узлы

  • Children * узла - это узлы, которые находятся на один уровень ниже его. Любые узлы за пределами одного уровня вложенности обычно называются потомками.

Property Gets

childNodes

Child Nodes

firstChild

First Child Node

lastChild

Last Child Node

children

Element Child Nodes

firstElementChild

First Child Element Node

lastElementChild

Last Child Element Node

Свойство + childNodes + будет возвращать живой список каждого дочернего элемента узла. Вы можете ожидать, что элемент + ul + получит три элемента + li +. Давайте проверим, что он получает.

ul.childNodes;
Output► (7) [text, li, text, li, text, li, text]

В дополнение к трем элементам + li + он также получает четыре текстовых узла. Это потому, что мы написали наш собственный HTML (он не был сгенерирован JavaScript), а отступ между элементами учитывается в DOM как текстовые узлы. Это не интуитивно понятно, поскольку вкладка Elements в DevTools удаляет пустые узлы.

Если бы мы попытались изменить цвет фона первого дочернего узла, используя свойство + firstChild +, это не удалось бы, потому что первый узел - текст.

ul.firstChild.style.background = 'yellow';
OutputUncaught TypeError: Cannot set property 'background' of undefined

Свойства + children +, + firstElementChild + и + lastElementChild + существуют в этих типах ситуаций для извлечения только узлов элементов. + ul.children вернет только три элемента` + li + `.

Используя + firstElementChild +, мы можем изменить цвет фона первого + li + в + ul +.

ul.firstElementChild.style.background = 'yellow';

Когда вы запустите приведенный выше код, ваша веб-страница будет обновлена ​​для изменения цвета фона.

изображение: https: //assets.digitalocean.com/articles/eng_javascript/dom/traverse-1.png [firstElementChild.style.background модификация]

При выполнении базовых манипуляций с DOM, таких как в этом примере, специфичные для элемента свойства чрезвычайно полезны. В сгенерированных JavaScript веб-приложениях свойства, которые выбирают все узлы, будут использоваться с большей вероятностью, так как в этом случае не будет новых пробелов и отступов.

Https://www.digitalocean.com/community/tutorials/how-to-construct-for-loops-in-javascript#forof-loop [+ for …​ of +] цикл может быть использован для перебора всех + children + elements.

for (let element of ul.children) {
 element.style.background = 'yellow';
}

Теперь каждый дочерний элемент будет иметь желтый фон.

изображение: https: //assets.digitalocean.com/articles/eng_javascript/dom/traverse-2.png [модификация дочерних элементов]

Поскольку наш элемент + p + содержит и текст, и элементы внутри него, свойство + childNodes + полезно для доступа к этой информации.

for (let element of p.childNodes) {
 console.log(element);
}
Output"The world's leading source on "
<strong>​shark​</strong>​
" related information."

+ childNodes + и + children + не возвращают массивы со всеми свойствами и методами Array, но они появляются и ведут себя аналогично массивам JavaScript. Вы можете получить доступ к узлам по номеру индекса или найти свойство + length.

document.body.children[3].lastElementChild.style.background = 'fuchsia';

Приведенный выше код найдет последний дочерний элемент (+ li +) четвертого дочернего элемента (+ ul +) + body + и применит стиль.

изображение: https: //assets.digitalocean.com/articles/eng_javascript/dom/traverse-3.png [последняя модификация дочернего элемента]

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

Узлы братьев и сестер

  • Братья и сестры * узла - это любой узел на одном уровне дерева в DOM. Братья и сестры не обязательно должны быть одного и того же типа узла - узлы текста, элемента и комментария могут быть братьями и сестрами.

Property Gets

previousSibling

Previous Sibling Node

nextSibling

Next Sibling Node

previousElementSibling

Previous Sibling Element Node

nextElementSibling

Next Sibling Element Node

Свойства родственного элемента работают так же, как и дочерние узлы, в том смысле, что существует набор свойств для обхода всех узлов и набор свойств только для узлов элементов. + previousSibling + и + nextSibling + получат следующий узел, который непосредственно предшествует или следует за указанным узлом, а + previousElementSibling + и + nextElementSibling + получат только узлы элемента.

В нашем примере + node.html + давайте выберем средний элемент + ul +.

const tiger = ul.children[1];

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

tiger.nextElementSibling.style.background = 'coral';
tiger.previousElementSibling.style.background = 'aquamarine';

Запуск этого кода должен был применить + коралл + к фону + Hammerhead + и + аквамарин + к фону + Great White +.

изображение: https: //assets.digitalocean.com/articles/eng_javascript/dom/traverse-4.png [модификация элемента родного брата]

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

Заключение

В этом руководстве мы рассмотрели, как получить доступ к корневым узлам каждого документа HTML и как пройтись по дереву DOM через свойства parent, child и sibling.

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