DOM-Node 接口:掌握网页灵魂的底层逻辑

28 阅读3分钟

前言

在 Web 开发中,我们每天都在操作 DOM。但你是否注意到,几乎所有的 DOM 对象(divpcomment 甚至 document)都拥有一套通用的属性和方法?这是因为它们都继承自 Node 接口。理解 Node,是深入掌握原生 JavaScript 操控网页的关键。

一、 Node 节点核心属性

Node 接口提供了一组标准属性,用于识别节点的身份和内容。

1. 节点类型标识

  • nodeType:通过数字常量快速判断节点身份。

    • 1 (Node.ELEMENT_NODE): 元素节点,如 <div>
    • 3 (Node.TEXT_NODE): 文本节点,包含空格和换行。
    • 8 (Node.COMMENT_NODE): 注释节点。
    • 9 (Node.DOCUMENT_NODE): 根节点 document
  • nodeName:对于元素节点,返回大写的标签名(如 "DIV")。

  • nodeValue:读写文本值,注意点——只有文本、注释、属性节点可以读写此值;对于元素节点,该值恒为 null


二、 节点关系网:纵横遍历

通过这些属性,你可以像在地图上移动一样在 DOM 树中穿梭。

属性描述
parentNode指向父节点
childNodes实时的子节点集合(包含文本和注释)
firstChild / lastChild第一个和最后一个子节点
previousSibling / nextSibling前一个和后一个兄弟节点
ownerDocument直接指向顶级的 document 对象

💡 避坑指南:

childNodes 是包含“空白文本节点”的。如果你只想获取标签元素,请使用 childrenfirstElementChild 等 Element 专有的属性。

image.png


三、 节点操作方法:增删改查

Node 接口提供的方法是所有 DOM 变动的基石。

1. 插入与替换

  • appendChild(node) :将节点添加到子节点列表的末尾。
  • insertBefore(newNode, refNode) :在参考节点前插入。如果 refNodenull,效果等同于 appendChild
  • replaceChild(newNode, oldNode) :替换旧节点。

2. 移除与克隆

  • removeChild(node) :移除子节点。注意: 节点并没有被销毁,只是从 DOM 树中剥离,方法会返回该节点的引用。

  • cloneNode(deep) :复制节点

    • true(深拷贝):复制节点及其内部所有子树。
    • false(浅拷贝):只复制节点本身及其属性。

3. 特殊工具方法

  • normalize() :清理工。它会合并相邻的文本节点,并删除空的文本节点。在复杂的 DOM 手动操作后非常有用。
  • contains(node) :判断传入的节点是否是当前节点的后代(包括自身),常用于点击外部关闭弹窗的逻辑。

四、 面试常见问答

Q1:NodeListHTMLCollection 有什么区别?

参考回答:

  • NodeList(由 childNodes 返回)可以包含任何节点类型。
  • HTMLCollection(由 children 返回)仅包含元素节点(Element)。
  • 两者通常都是实时的(Live) ,即 DOM 改变,集合会自动更新(但 querySelectorAll 返回的是静态的)。

Q2:如何判断一个节点是否含有子节点?

参考回答:

除了检查 childNodes.length,更优雅的方法是调用 node.hasChildNodes(),它返回一个布尔值。

Q3:cloneNode 会复制绑定在元素上的事件吗?

参考回答:

不会。 cloneNode 只复制 HTML 属性(包括 inline 事件如 onclick="..."),但不会复制通过 addEventListener 绑定的 JavaScript 事件。