JavaScript

Часть 1, Часть 2, Часть 3

Навигация по DOM элементам

Обход DOM или, проще говоря, навигация по DOM элементам — это работа со свойствами родительских, дочерних и соседних DOM элементов с помощью JavaScript.

В качестве примера мы будем использовать следующий код:

<!DOCTYPE html>
<html>
<head>
  <title>Traversing the DOM</title>
</head>
<body>
  <h1>Traversing the DOM</h1>
  <p>Let's work with this example to <strong>MASTER</strong> the DOM!</p>
  <h2>List of Items..</h2>
  <ul>
    <li>Pizza</li>
    <li>Burgers</li>
    <li>Doritos</li>
  </ul>
</body>
<script>
  const h1 = document.getElementsByTagName('h1')[0];
  const p = document.getElementsByTagName('p')[0];
  const ul = document.getElementsByTagName('ul')[0];
</script>
</html>

В браузере файл будет выглядеть следующим образом:

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

Объект document — это корень каждого узла в DOM. Следующий уровень — это объект window, который включает в себя закладки браузера, тулбары, функции promt и alert. Мы будем работать с DOM и, таким образом, с объектом document, который включает в себя все, что находится внутри window.

По умолчанию каждый документ содержит html, head, и body.

Проверить содержимое каждого элемента можно, набрав в консоли:

document.head; // ► <head>…</head>
document.body; // ► <body>…</body>

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

Как упоминалось ранее, узлы в DOM делятся на родительские, дочерние и соседние в зависимости от их связи с другими узлами. Родитель конкретного узла — это узел, который находится на уровень выше в иерархии DOM.

В нашем примере:

  • html является родителем head, body, и script
  • body является родителем h1, h2, p и ul, но не li, так как li на два уровня ниже body

Мы можем проверить родителя p элемента с помощью parentNode свойства. Так как мы присвоили p переменной, необходимо просто ввести:

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

Можно даже подняться на два уровня выше:

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

Дочерние узлы

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

В данной статье мы будем работать со следующими свойствами: childNodes, firstChild, lastChild, children, firstElementChild и lastElementChild.

Начнем со свойства childNodes, которое вернет список каждого дочернего элемента данного узла:

ul.childNodes // ► NodeList(7) [text, li, text, li, text, li, text]

Возможно, вы ожидали, что вернется только три элемента li? Текстовые узлы на самом деле пробелы, вызванные отступами между элементами, которые DOM воспринимает как узлы. Их не будет видно во вкладке Elements, так как консоль разработчика удаляет эти узлы автоматически.

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

ul.firstChild.style.background = "purple";
// результат:
Uncaught TypeError: Cannot set property 'background' of undefined

Когда нам необходимо работать только с узлами элементов, можно использовать children, firstElement и lastElementChild.

ul.children вернет только три li элемента.

Для того, чтобы изменить только первый элемент li, используйте:

ul.firstElementChild.style.background = ‘purple’;

Так выглядит обновленная страница:

Если необходимо изменить все четыре дочерних элемента, вы можете использовать for .. of цикл следующим образом:

for (let element of ul.children) {
 element.style.background = ‘purple’;
}
for (let element of ul.children) {
element.style.background = ‘purple’;
}

Теперь все дочерние элементы изменили цвет фона:

Если посмотреть на элемент p, мы увидим, что он содержит как текст, так и другой элемент (тег strong).

for (let element of p.childNodes) {
console.log(element);
}
// результат:
"Let's work with this example to " 
<strong>MASTER</strong>
" the DOM!"

Свойство childNodes полезно, когда необходимо получить доступ к информации.

Как childNodes, так и children возвращают не стандартный JavaScript массив (со всеми методами и свойствами), а объект, подобный массиву. Однако, как и с массивом, доступ к узлам можно получить через номер индекса или даже найти свойство length.

document.body.children[3].lastElementChild.style.background = ‘pink’;

В этом коде мы получаем доступ к последнему дочернему элементу li из четырех элементов ul в body и применяем стили.

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

Соседние элементы

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

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

Получим средний элемент списка ul:

const burger = ul.children[1];

Также воспользуемся свойствами соседнего элемента для получения доступа к следующему и предыдущему элементам (избегая текстовых пробелов).

burger.nextElementSibling.style.background = ‘orange’;
burger.previousElementSibling.style.background = ‘green’;

Изменения будут выглядеть следующим образом:

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

Читайте также:


Перевод статьи Timothy Robards: JavaScript Fundamentals: Master the DOM! (Part 2)