Вступление
Предыдущий учебник в этой серии, 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 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
Поскольку элементы + html,` + head` и + body + очень распространены, они имеют свои собственные свойства в + document.
Откройте Console в DevTools и протестируйте каждое из этих четырех свойств, отправив их и просмотрев выходные данные. Вы также можете проверить + h1 +, + p + и + ul +, которые будут возвращать элементы из-за переменных, которые мы добавили в тег + script +.
Родительские узлы
Узлы в DOM называются родителями, детьми и братьями и сестрами, в зависимости от их отношения к другим узлам. * Parent * любого узла - это узел, который находится на один уровень выше него или ближе к + document + в иерархии DOM. Есть два свойства для получения родителя - + parentNode + и + parentElement +.
| Property | Gets |
|---|---|
Parent Node |
|
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 |
|---|---|
Child Nodes |
|
First Child Node |
|
Last Child Node |
|
Element Child Nodes |
|
First Child Element Node |
|
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 |
|---|---|
Previous Sibling Node |
|
Next Sibling Node |
|
Previous Sibling Element Node |
|
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 любого веб-сайта.