JavaScript с нуля - [61]

Шрифт
Интервал

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, которое сообщает, с каким количеством потомков взаимодействует родитель. Если у вас уже голова пошла кругом, не переживайте. Код из следующего раздела прояснят сказанное.

Складываем все воедино

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

Проверка наличия потомка

Чтобы проверить, есть ли у элемента потомок, мы можем сделать следующее:

let bodyElement = document.querySelector("body");


if (bodyElement.firstChild) {

// Делает что-нибудь интересное

}

Эта инструкция if вернет null, если потомков не существует. Мы могли бы также использовать bodyElement.lastChild или bodyElement.children.count, если бы любили много печатать, но я предпочитаю простые варианты.

Обращение ко всем потомкам

Если нужно обратиться ко всем потомкам родителя, всегда можно прибегнуть к старому доброму циклу for:

let bodyElement = document.body;


for (let i = 0; i < bodyElement.children.length; i++) {

let childElement = bodyElement.children[i];


document.writeln(childElement.tagName);


Рекомендуем почитать
Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


MFC и OpenGL

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


Симуляция частичной специализации

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


Обработка событий в С++

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


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.