文档对象模型(DOM)是将 HTML 或 XML 文档视为树结构的接口,其中每个节点(node)都是文档的对象。DOM 还提供了一组用于查问树、批改构造和款式的办法。
DOM 还应用了术语 元素(element):它与节点十分类似。那么 DOM 节点和元素之间有什么区别呢?
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 个子节点为文本节点:"Thank you for visiting my web page!"
。
节点类型
那么怎么辨别这些节点的类型呢?答案在于 DOM Node 接口,尤其是在 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
DOM 元素
把握了 DOM 节点的常识之后,当初该辨别 DOM 节点和元素了。
如果你了解了什么事节点,那么答案很显著:元素是特定类型的节点——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
简略的说,元素是节点的子类型,就像猫是动物的子类型一样。
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>
查看 parapgraph 节点的 childNodes
和 children
属性:
const paragraph = document.querySelector('p');
paragraph.childNodes; // NodeList: [HTMLElement, Text]
paragraph.children; // HTMLCollection: [HTMLElement]
paragraph.childNodes
汇合蕴含 2 个节点:粗体元素 <b>Thank you</b>
,以及文本节点 for visiting my web page!
。
然而 paragraph.children
汇合仅蕴含 1 个我的项目:粗体元素 <b>Thank you</b>
。
因为 paragraph.children
仅蕴含元素,所以这里没有蕴含文本节点,因为其类型是文本(Node.TEXT_NODE
),而不是元素(Node.ELEMENT_NODE
)。
同时领有 node.childNodes
和 node.children
,你能够抉择要拜访的子级汇合:是所有子级节点还是只有是元素的子级。
总结
DOM 文档是节点的分层汇合。每个节点能够有父级或子级。
如果理解了什么是节点,那么理解 DOM 节点和元素之间的区别就很容易。
节点具备类型,元素类型是其中之一。元素由 HTML 文档中的标签示意。
最初考考你:哪种类型的节点永远没有父节点?
本文首发微信公众号:前端先锋
欢送扫描二维码关注公众号,每天都给你推送陈腐的前端技术文章
欢送持续浏览本专栏其它高赞文章:
- 深刻了解 Shadow DOM v1
- 一步步教你用 WebVR 实现虚拟现实游戏
- 13 个帮你进步开发效率的古代 CSS 框架
- 疾速上手 BootstrapVue
- JavaScript 引擎是如何工作的?从调用栈到 Promise 你须要晓得的所有
- WebSocket 实战:在 Node 和 React 之间进行实时通信
- 对于 Git 的 20 个面试题
- 深刻解析 Node.js 的 console.log
- Node.js 到底是什么?
- 30 分钟用 Node.js 构建一个 API 服务器
- Javascript 的对象拷贝
- 程序员 30 岁前月薪达不到 30K,该何去何从
- 14 个最好的 JavaScript 数据可视化库
- 8 个给前端的顶级 VS Code 扩大插件
- Node.js 多线程齐全指南
- 把 HTML 转成 PDF 的 4 个计划及实现
- 更多文章 …