Выбрать главу

Поехали!

Поиск пути

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

Вид вершины нашей DOM представлен элементами window, document и html (рис. 28.2).

Рис. 28.2. Вид вершины этого дерева всегда одинаков

В связи с повышенной важностью этих трех элементов DOM предоставляет к ним легкий доступ посредством window, document и document.documentElement:

let windowObject = window; // хм-м….

let documentObject = document; // Это наверняка необязательно

let htmlElement = document.documentElement;

Здесь стоит отметить, что и window, и document являются глобальными свойствами. Нам не обязательно явно объявлять их подобно тому, как сделал я. Используйте их сразу.

Как только мы спускаемся ниже уровня HTML-элемента, наша DOM начинает ветвление и становится гораздо интереснее. С этого места можно использовать несколько способов навигации. Один из них мы уже видели многократно, и связан он с использованием querySelector и querySelectorAll для получения в точности тех элементов, которые нам нужны. На практике зачастую эти два метода слишком ограничены.

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

Разобраться нам поможет знание того, что все элементы в DOM имеют по меньшей мере одну комбинацию родителей, братьев (соседних элементов) и потомков, на которых можно ориентироваться. Для наглядного представления посмотрите на ряд, содержащий элементы div и script, как показано на рис. 28.3.

Элементы div и script являются братьями, так как имеют одного родителя — элемент body. Элемент script не имеет потомков, но у div, напротив, они есть. Img, h1, p и div являются потомками элемента div, при этом все потомки одного родителя между собой являются братьями. Как и в реальной жизни, положение родителя, потомка и брата зависит от того, на какой части дерева мы фокусируемся. То есть практически каждый элемент в зависимости от угла обзора может выступать в различных ролях.

Для упрощения работы с этим всем у нас есть несколько свойств, на которые мы и будем полагаться. Ими являются firstChild, lastChild, parentNode, children, previousSibling и nextSibling. Просто глядя на их названия, вы можете догадаться, какую именно роль они играют. Дьявол в деталях, поэтому рассмотрим все подробно.

Рис. 28.3. Пример нашего дерева с родителями, братьями и потомками

Работа с братьями и родителями

Из всех свойств легче всего работать с относящимися к родителям и братьям, а именно parentNode, previousSibling и nextSibling. Схема на рис. 28.4 дает представление о том, как эти свойства работают.

Рис. 28.4. Связь между братьями и родителями с позиции DOM

Схема несколько перегружена, но понять, что на ней происходит, можно. Свойство parentNode указывает на родителя элемента. Свойства previousSibling и nextSibling позволяют элементу найти его предыдущего или следующего брата — если мы будем следовать по стрелкам на рисунке, то увидим это. В нижней строке nextSibling нашего img это div. previousSibling для div — это img. Обращение к parentNode в любом из этих элементов приведет вас к родителю div во втором ряду. Здесь все достаточно понятно.

Давай заведем детей!

Менее понятно, как во все это вписываются потомки. Поэтому давайте взглянем на свойства firstChild, lastChild и children, показанные на рис. 28.5.

Рис. 28.5. Представление потомков и их потомков

Свойства firstChild и lastChild относятся к первому и последнему дочерним элементам родителя. Если у родителя есть всего один потомок, как в случае с элементом body из нашего примера, тогда и firstChild, и lastChild будут указывать на одно и то же. Если у элемента нет потомков, то эти свойства будут возвращать null.

Самое хитрое из всех этих свойств — свойство children. Когда вы обращаетесь к свойству children в родителе, то по умолчанию получаете коллекцию дочерних элементов, которые у него есть. Эта коллекция не является Array, но при этом имеет некоторые присущие массиву возможности. Как и в случае с массивом, вы можете перебирать эту коллекцию или обращаться к ее потомкам по отдельности. У этой коллекции есть свойство length, которое сообщает, с каким количеством потомков взаимодействует родитель. Если у вас уже голова пошла кругом, не переживайте. Код из следующего раздела прояснят сказанное.