В чём разница между узлом и элементом DOM?

в 14:51, , рубрики: html, Блог компании RUVDS.com, разработка, Разработка веб-сайтов

Объектная модель документа (Document Object Model, DOM) — это интерфейс, который рассматривает HTML- или XML-документы в виде древовидных структур, каждый узел которых является объектом документа. DOM, кроме того, предоставляет набор методов для выполнения запросов к дереву документа, для изменения его структуры и для выполнения с ним некоторых других действий.

В чём разница между узлом и элементом DOM? - 1

При работе с DOM, кроме того, используется термин «элемент». Элементы очень похожи на узлы, но, всё же, это — не одно и то же. В чём же разница?

1. Узел DOM

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

Если рассматривать ситуацию в общих чертах, то оказывается, что DOM-документ включает в себя иерархию узлов. У каждого узла может быть родитель и (или) потомок.

Посмотрим на следующий HTML-документ:

<!DOCTYPE html>
<html>
  <head>
    <title>My Page</title>
  </head>
  <body>
    <!-- Page Body -->
    <h2><font color="#3AC1EF">My Page</font></h2>
    <p id="content">Thank you for visiting my web page!</p>
  </body>
</html>

В документ входит следующая иерархия узлов:

В чём разница между узлом и элементом DOM? - 2

DOM-представление документа

<html> — это узел в дереве документа. У него есть два дочерних узла — <head> и <body>.

У <body> есть три дочерних узла — комментарий <!-- Page Body -->, заголовок <h2><font color="#3AC1EF"> и абзац <p>. Родительским элементом узла <body> является узел <html>.

Теги в HTML-документе представляют узлы. Интересно то, что обычный текст — это тоже узел. Узел-абзац <p> имеет потомка — текстовый узел Thank you for visiting my web page!.

▍Типы узлов

Как различать узлы разных типов? Ответ кроется в интерфейсе DOM, который носит имя Node. В частности — речь идёт о свойстве Node.nodeType.

Это свойство может иметь одно из следующих значений, представляющих тип узла:

  • Node.ELEMENT_NODE
  • Node.ATTRIBUTE_NODE
  • Node.TEXT_NODE
  • Node.CDATA_SECTION_NODE
  • Node.PROCESSING_INSTRUCTION_NODE
  • Node.COMMENT_NODE
  • Node.DOCUMENT_NODE
  • Node.DOCUMENT_TYPE_NODE
  • Node.DOCUMENT_FRAGMENT_NODE
  • Node.NOTATION_NODE

Имена констант указывают на тип узла. Например, Node.ELEMENT_NODE представляет узел-элемент, Node.TEXT_NODE — это текстовый узел, Node.DOCUMENT_NODE — это узел-документ и так далее.

Например, давайте выберем узел-абзац и посмотрим на его свойство nodeType:

const paragraph = document.querySelector('p');

paragraph.nodeType === Node.ELEMENT_NODE; // => true

Свойство paragraph.nodeType, как и ожидалось, содержит значение Node.ELEMENT_NODE, которое указывает на то, что абзац — это элемент.

В абзаце, кроме того, имеется текстовый узел:

const paragraph = document.querySelector('p');
const firstChild = paragraph.childNodes[0];

firstChild.nodeType === Node.TEXT_NODE; // => true

Есть тип узла, который представляет всё дерево узлов документа. Это — Node.DOCUMENT_NODE:

document.nodeType === Node.DOCUMENT_NODE; // => true

2. Элемент DOM

После того, как мы разобрались с тем, что такое узел DOM, пришло время поговорить том, чем различаются узлы и элементы DOM.

Если вы как следует вникли в сущность термина «узел», то вам уже всё должно быть понятно. Элемент — это узел особого типа — Node.ELEMENT_NODE. Это — такой же тип узла, как и другие, представляющие весь документ, комментарии, тексты и прочие узлы DOM.

Если говорить простыми словами, то элемент — это узел, который объявлен с использованием тега в HTML-документе. <html>, <head>, <title>, <body>, <h2><font color="#3AC1EF">, <p> — это всё элементы, так как они представлены тегами.

А вот сам документ, комментарий, текст — это не элементы, так как они не представлены соответствующими тегами:

<!DOCTYPE html>
<html>
  <body>
    <!-- Page Body -->
    <p>
      Thank you for visiting my web page!
    </p>
  </body>
</html>

В DOM-API JavaScript конструктор узла — это Node, а HTMLElement — это конструктор элемента. Абзац, хотя это и узел DOM, является ещё и элементом, соответствующий объект является и экземпляром Node, и экземпляром HTMLElement:

const paragraph = document.querySelector('p');

paragraph instanceof Node;        // => true
paragraph instanceof HTMLElement; // => true

Если говорить простыми словами, элемент — это подтип узла — так же как кошка — подтип животного.

3. Свойства DOM: узлы и элементы

Помимо различения узлов и элементов нужно ещё различать свойства DOM, которые содержат исключительно узлы или исключительно элементы.

Следующие свойства могут содержать либо узел (Node), либо коллекцию узлов (NodeList):

node.parentNode; // Node или null

node.firstChild; // Node или null
node.lastChild;  // Node или null

node.childNodes; // NodeList

А вот следующие свойства могут содержать либо элементы (HTMLElement), либо коллекции элементов (HTMLCollection):

node.parentElement; // HTMLElement или null

node.children;      // HTMLCollection

Так как и свойство node.childNodes, и свойство node.children возвращает коллекцию сущностей-потомков, возникает вопрос о том, почему существуют оба этих свойства. На самом деле это — хороший вопрос!

Рассмотрим следующий элемент-абзац, содержащий какой-то текст:

<p>
  <b>Thank you</b> for visiting my web page!
</p>

Откройте этот демонстрационный пример и посмотрите на свойства childNodes и children узла-абзаца:

const paragraph = document.querySelector('p');

paragraph.childNodes; // NodeList:       [HTMLElement, Text]
paragraph.children;   // HTMLCollection: [HTMLElement]

Коллекция paragraph.childNodes содержит 2 узла: текст, оформленный полужирным шрифтом с помощью тега <b> (<b>Thank you</b>), и текстовый узел (for visiting my web page!).

Но в коллекции paragraph.children имеется лишь 1 элемент, представленный тегом <b> (<b>Thank you</b>).

Так как свойство paragraph.children содержит только элементы, текстовый узел в него не включён. Произошло это из-за того, что с точки зрения системы это — текст (Node.TEXT_NODE), а не элемент (Node.ELEMENT_NODE).

То, что у нас есть и node.childNodes, и node.children, позволяет нам выбирать именно ту коллекцию элементов-потомков некоего узла DOM, с которой нужно работать. Это может быть либо коллекция, содержащая все узлы-потомки, либо только те узлы-потомки, которые являются элементами.

4. Итоги

Документ DOM — это иерархическая коллекция узлов. У каждого узла могут быть родители и (или) потомки.

Отличие между узлами и элементами DOM становится очевидным в том случае, если есть понимание того, что такое узел.

У узлов имеется свойство, указывающее на их тип. Один из этих типов соответствует элементам DOM. Элементы представлены тегами в HTML-документе.

Сталкивались ли вы со сложностями, касающимися различения узлов и элементов DOM?

Автор: ru_vds

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js