От автора: объектная модель документа (DOM) — это интерфейс, который обрабатывает документ HTML или XML как древовидную структуру, где каждый узел является объектом документа. DOM также предоставляет набор методов для запроса дерева, изменения структуры и стиля.
В DOM также используется термин элемент: который очень похож на узел. Итак, в чем разница между узлом DOM и элементом в DOM? Давайте выясним!
1. Узел DOM
Ключом к пониманию разницы между узлом и элементом является понимание того, что такое узел. С более высокой точки зрения, документ DOM состоит из иерархии узлов. Каждый узел может иметь родителя и / или потомков.
Давайте посмотрим на следующий HTML-документ:
<!DOCTYPE html> <html> <head> <title>My Page</title> </head> <body> <!-- Page Body --> <h2>My Page</h2> <p id="content">Thank you for visiting my web page!</p> </body> </html>
Документ содержит следующую иерархию узлов:
<html> это узел в дереве документа. У него есть 2 дочерних элемента: узлы <head> и <body>.
<body> также является узлом, имеющим 3 дочерних элемента: комментарий <!— Page Body —>, заголовок <h2> и абзац <p>. Родителем узла <body> является узел <html>.
Теги в HTML-документе представляют собой узел, что интересно, так это то, что обычный текст также является узлом. Узел абзаца <p> имеет 1 дочерний элемент: текстовый узел «Спасибо, что посетили мою страничку!».
1.2 Типы узлов
Как отличить эти разные типы узлов? Ответ кроется в интерфейсе узла DOM, особенно в свойстве Node.nodeType.
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.ELEMENT_NODE). Наряду с такими типами, как документ, комментарий, текст и т.д.
Проще говоря, элемент — это узел, который записывается с помощью тега в документе HTML. <html>, <head>, <title>, <body>, <h2>, <p> все элементы, так как они представлены тегами.
Тип документа, комментарий, текстовые узлы не являются элементами, потому что они не записаны с тегами:
<!DOCTYPE html><html> <body> <!-- Page Body --> <p> Thank you for visiting my web page! </p> </body> </html>
Node является конструктором узла и HTMLElement конструктором элемента в JavaScript DOM. Абзац, будучи узлом и элементом, является экземпляром обоих Node и HTMLElement:
const paragraph = document.querySelector('p'); paragraph instanceof Node; // => true paragraph instanceof HTMLElement; // => true
Проще говоря, элемент — это подтип узла, так же как кошка — подтип животного.
3. Свойства модели DOM: узлы и элементы
Помимо различения узлов от элементов, вам также необходимо различать свойства DOM, которые содержат только узлы или только элементы. Следующие свойства типа Node оценивают узел или группу узлов (NodeList):
node.parentNode; // Node or null node.firstChild; // Node or null node.lastChild; // Node or null node.childNodes; // NodeList
Однако следующие свойства являются элементами или группой элементов (HTMLCollection):
node.parentElement; // HTMLElement or 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>, а также текстовый узел – что посетили мою страничку!
Однако в группе paragraph.children всего 1 элемент: выделенный жирным шрифтом <b> Спасибо,</b>.
Поскольку paragraph.children содержит только элементы, текстовый узел не был включен сюда, потому что его тип — text (Node.TEXT_NODE), а не element (Node.ELEMENT_NODE).
Наличие обоих node.childNodes и node.children позволяет вам выбрать группу дочерних элементов, к которым вы хотите получить доступ: все дочерние узлы или только дочерние элементы, являющиеся элементами.
4. Заключение
Документ DOM — это иерархический набор узлов. Каждый узел может иметь родителя и / или потомков. Понять разницу между узлом DOM и элементом легко, если вы понимаете, что такое узел. У узлов есть типы, одним из которых является тип элемента. Элемент представлен тегом в документе HTML.
Тест: какой тип узла никогда не имеет родительского узла?
Автор: Dmitri Pavlutin
Источник: dmitripavlutin.com
Редакция: Команда webformyself.