Меню
Спросить
JS

Работа с DOM. Объект Node

16 ноября 2017
Работа с DOM. Объект Node

Всем привет! В прошлой статье мы учились основам выборки элементов дерева DOM. Сегодня нам предстоит углубиться в дерево DOM и познакомится с двумя объектами Node и Element. Перечислю свойства этих объектов, которые мы сегодня пройдем - parentNode, childNodes, firstChild, lastChild, nextSibling, previousSibling, nodeType, nodeValue, nodeName, firstElementChild, lastElementChild, nextElementSibling, previousElementSibling и childElementCount. Конечно, пока вам это все не знакомо и глухо, но вскоре вы начнете в этом разбираться, по крайней мере я надеюсь на вас =).
Начнем с того, что мы говорили в прошлой статье про дерево DOM, а именно, что оно состоит из элементов html, но сегодня, как я уже сказал, мы будем копать глубже, поэтому сразу стоит сказать, что DOM или наш html документ состоят из так называемых узлов, которые в свою очередь мы можем представить в виде объекта Node. Это могут быть узлы элементов или текстовые узлы и прочие, и все они связаны между собой, поэтому они и называются узлы.
Чтобы было понятней, давайте рассмотрим пример.

  1. <div>Текст</div>
  2. <!--Комментарий-->

Сколько элементов html мы здесь видим? Кто-то скажет один, кто-то скажет два. Первый - это div блок, а второй - комментарий. Но ведь комментарии не видны на странице html в браузере, значит он не является элементом html? Он не является элементом страницы для обычного пользователя, он его не видит, но является частью кода html для верстальщика, он его написал и видит. Но мы программисты на JavaScript и здесь мы должны видеть не один элемент и не два элемента, здесь на самом деле 5 узлов дерева DOM. Кого-то это повергло в шок и недоумение, срочно принесите воды.
А теперь давайте проясним, что это за 5 узлов.
Первый узел - это узел элемента, а конкретно элемента с тегом DIV.
Второй узел - это текстовый узел со значением "Текст".
Третий узел - это текстовый узел со значением - переход на новую строку или ENTER.
Четвертый узел - это узел комментария.
Пятый узел - это текстовый узел, со значением "Комментарий".
Вот как на самом деле выглядит данное DOM дерево.

Узлы дерева DOM

Все эти узлы вы будете знать и понимать при помощи объекта Node, а точнее его свойств, которые мы рассмотрим ниже.
Я буду использовать все тот же html документ из прошлой части, но немного его изменив.

  1. <!document html>
  2. <html>
  3.     <head>
  4.         <script src="script.js" async></script>
  5.     </head>
  6.     <body>
  7.         <ul id="nav">
  8.             <li id="gl">Главная</li>
  9.             <li id="nw">Новости</li>
  10.             <li id="vh">Вход</li>
  11.             <li id="rg">Регистрация</li>
  12.         </ul>
  13.         <!--Комментарий-->
  14.         <div name="block">as</div>
  15.     </body>
  16. </html>

Открываем script.js и объявляем переменную el, в которой будет обращение к элементу body.

  1. var
  2. el = document.body;

Свойство childNodes

Первое свойство объекта Node, которое мы рассмотрим называется childNodes, оно нам предоставляет список тех самых узлов элемента, для примера давайте посмотрим из каких узлов состоит наш body, поэтому дописываем к обращению данное свойство и выводим переменную в консоль.

  1. var
  2. el = document.body.childNodes;
  3. console.log(el);

И так в консоли у меня вышло 7 узлов.

  1. text - ENTER
  2. ul#nav - маркированный список ul
  3. text - ENTER
  4. comment - комментарий
  5. text - ENTER
  6. div - блок div
  7. text - ENTER

Каждый узел в свою очередь, кроме текстовых и комментариев, имеет свои наборы узлов, так например маркированный список ul состоит из текстовых узлов и элементов li. В целом и получается, что дерево DOM состоит из множества таких узлов, если представлять DOM в виде объекта Node.
Поехали дальше.

Свойство parentNode

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

  1. var
  2. el = document.getElementById('nav');
  3. console.log(el);

И посмотрим с помощью свойства parentNode, какой у него родитель.

  1. var
  2. el = document.getElementById('nav').parentNode;
  3. console.log(el);

Как и ожидалось в консоли выходит родитель body, все верно.

Свойства firstChild и lastChild

Эти два свойства показывают дочерние узлы элемента, а именно первый и последний узел соответственно.
То есть:
firstChild - первый дочерний узел элемента,
lastChild - последний дочерний узел.
Если мы испробуем на том же элементе, что и выше, то и первый и последний будут текстовыми, поэтому давайте удалим текстовый узлы и напишем список слитно.

  1. <ul id="nav"><li id="gl">Главная</li>
  2.     <li id="nw">Новости</li>
  3.     <li id="vh">Вход</li>
  4.     <li id="rg">Регистрация</li></ul>

И испробуем данные свойства.

  1. var
  2. el = document.getElementById('nav').firstChild;
  3. console.log(el);
  4. // <li id="gl">Главная</li>
  5. // Это был первый дочерний узел, теперь последний
  6. el = document.getElementById('nav').lastChild;
  7. console.log(el);
  8. // <li id="rg">Регистрация</li>

Свойства nextSibling и previousSibling

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

  1. ....
  2.     <body>
  3.         <ul id="nav">....</ul><!--Комментарий-->
  4.     </body>
  5. ....

Теперь испробуем свойства.

  1. var
  2. el = document.getElementById('nav').nextSibling;
  3. console.log(el);
  4. // <!--Комментарий-->
  5. // Это был узел после элемента, теперь узел до элемента
  6. el = document.getElementById('nav').previousSibling;
  7. console.log(el);
  8. // #text

Поехали дальше.

Свойство nodeName

Данное свойство показывает нам имя тега выбранного элемента. Давайте выберем другой элемент, например пункт LI с идентификатором vh, в принципе нет разницы какой конкретно пункт выбирать.

  1. var
  2. el = document.getElementById('vh');
  3. console.log(el);

И теперь проверим какое имя тега у данного элемента.

  1. var
  2. el = document.getElementById('vh').nodeName;
  3. console.log(el);
  4. // LI

Свойство nodeValue

С помощью данного свойства можно получить значение текстового узла или узла комментария, с другими узлами это не сработает. Если мы сейчас попытаемся получить текст внутри пункта LI, то ни чего не получится, точнее получится, но результат будет null. Почему так? Потому что, пункт LI является узлом с типом элемент, он не является текстовым узлом.
Мы можем обратиться к пункту LI с идентификатором vh или любым другим из имеющихся:

  1. var
  2. el = document.getElementById('vh');
  3. console.log(el);

Но как обратится к текстовому узлу внутри него? Тут мы можем воспользоваться свойством firstChild, описанным выше, которое как раз таки вернет нам первый дочерний узел данного элемента, а первый дочерний узел - текстовый узел, с него то мы и сможем получить заветный текст.
Поэтому, обратились к элементу, теперь обратимся к его первому дочернему узлу.

  1. var
  2. el = document.getElementById('vh').firstChild;
  3. console.log(el);

А теперь можем получить и значение данного текстового узла.

  1. var
  2. el = document.getElementById('vh').firstChild.nodeValue;
  3. console.log(el);
  4. // Вход

Свойство nodeType

Данное свойство может нам предоставить тип узла элемента, он вернет число, которое соответствует определенным узлам объекта Node.
Число 1 - это узел элемента, например тег LI или UL,
число 3 - это текстовый узел,
число 8 - это комментарий.
Полный список типов узлов можно посмотреть например здесь. Давайте проверим несколько узлов.
Тот самый текстовый узел

  1. var
  2. el = document.getElementById('vh').firstChild.nodeType;
  3. console.log(el);
  4. // 3

Сам пункт LI

  1. var
  2. el = document.getElementById('vh').nodeType;
  3. console.log(el);
  4. // 1

Свойство childElementCount

До этого мы работали с узлами выбранного элемента, но бывает, что не всегда нужно работать со всему узлами элемента, бывает что нужно работать именно с одним из узлов - узел типа элемент. То есть работа с элементами элемента, не затрагивая текстовые узлы или комментарии к примеру.
Свойство childElementCount вернет число элементов, которые находятся внутри выбранного элемента. Проще говоря мы можем узнать сколько элементов внутри.
Например, посмотрим сколько элементов внутри нашего списка.

  1. var
  2. el = document.getElementById('nav').childElementCount;
  3. console.log(el);
  4. // 4

Вернул число 4, все верно, ведь внутри нашего списка четыре пункта, то есть четыре элемента LI.

Свойства nextElementSibling и previousElementSibling

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

Свойства firstElementChild и lastElementChild

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

Заключение

Думаю на сегодня будет достаточно информации для переваривания. Всем спасибо, пока =)

Следующая статьяПредыдущая статья