学习笔记:JavaScript(4)——DOM节点

DOM 节点:网页结构的核心单元

在前端开发中,DOM(Document Object Model,文档对象模型) 是浏览器将 HTML/XML 文档解析后形成的 "树形结构",而 DOM 节点(Node) 则是这棵树的基本组成单元 ------ 每个 HTML 标签、文本、注释甚至属性,都对应一个 DOM 节点。理解 DOM 节点是操作网页(如修改内容、样式、结构)的基础。

一、DOM 节点的本质与作用

浏览器加载 HTML 后,会将代码 "翻译" 成一个 DOM 树

  • 树根是 document(代表整个文档);
  • 树干 / 树枝是 HTML 标签(如 <html><body><div>);
  • 树叶可能是文本(如 <p> 里的文字)、注释或属性。

我们通过 JavaScript 操作 DOM 节点,就能实现网页的 "动态交互"------ 比如点击按钮修改文本、添加新元素、删除广告等,本质都是在操作 DOM 节点。

二、DOM 节点的 5 种核心类型

不同的 HTML 内容对应不同类型的节点,每种节点有专属的属性和方法,最常用的是前 4 种:

节点类型 描述 示例(对应 HTML 代码) 核心特征
元素节点(Element) 最核心的节点类型,对应 HTML 标签(如 <div><p><button> <div class="box">Hello</div> 中的 <div> 可通过 tagName 获取标签名(如 DIV
文本节点(Text) 对应标签内的文本内容(不包含标签本身) 上述 <div> 中的 "Hello" 内容通过 nodeValue 属性获取 / 修改
属性节点(Attr) 对应 HTML 标签的属性(如 classidsrc 上述 <div>class="box" 通常通过元素节点的 attributes 访问
注释节点(Comment) 对应 HTML 中的注释(<!-- 注释内容 --> <!-- 这是一个盒子 --> nodeValue 为注释文本,不显示在页面
文档节点(Document) 代表整个 HTML 文档(DOM 树的根),所有其他节点都是它的 "后代" 全局对象 document 就是文档节点 提供创建 / 查找节点的方法(如 getElementById

三、DOM 节点的核心属性(通用 + 专属)

所有 DOM 节点都继承自 Node 接口,拥有一些通用属性;不同类型的节点还有专属属性。

1. 所有节点通用的核心属性

属性名 作用
nodeType 节点类型(用数字表示):1 = 元素节点、3 = 文本节点、8 = 注释节点、9 = 文档节点
nodeName 节点名称:元素节点是标签名(大写,如 DIV)、文本节点是 #text、注释节点是 #comment
nodeValue 节点值:文本节点是文本内容、注释节点是注释内容、元素节点为 null
parentNode 获取当前节点的 "父节点"(每个节点只有一个父节点,document 没有父节点)
childNodes 获取当前节点的 "所有子节点"(返回 NodeList 类数组,包含文本、注释等)
previousSibling/nextSibling 获取当前节点的 "前一个兄弟节点"/"后一个兄弟节点"(可能包含空白文本节点)

2. 元素节点(Element)的专属属性

元素节点是最常用的节点类型,除了通用属性,还有专门操作标签的属性:

属性名 作用 示例
tagName 获取元素标签名(大写,与 nodeName 一致,但更直观) document.querySelector('div').tagNameDIV
id 获取 / 设置元素的 id 属性 div.id = "new-id"
className 获取 / 设置元素的 class 属性(因 class 是 JS 关键字,故用 className div.className = "box red"
classList 操作元素的 class(更灵活,支持添加、删除、判断) div.classList.add("active")(添加类)
attributes 获取元素的 "所有属性节点"(返回 NamedNodeMap 类数组) div.attributes → 包含 classid 等属性
innerHTML 获取 / 设置元素的 "内部 HTML 内容"(可解析标签) div.innerHTML = "<p>新内容</p>"
textContent 获取 / 设置元素的 "内部文本内容"(不解析标签,只保留文本) div.textContent = "新文本"

四、DOM 节点的核心操作(增删改查)

前端开发中,对 DOM 节点的操作主要围绕 "查找、创建、修改、删除、插入" 展开,核心方法如下:

1. 查找节点(获取已有节点)

通过 document 或父元素调用方法,找到目标节点(最常用前 3 种):

方法名 作用 示例
getElementById(id) 通过 id 查找元素节点(唯一,返回单个节点) document.getElementById("box")
getElementsByClassName(class) 通过 class 查找元素节点(返回 HTMLCollection 类数组) document.getElementsByClassName("red")
getElementsByTagName(tag) 通过标签名查找元素节点(返回 HTMLCollection 类数组) document.getElementsByTagName("div")
querySelector(selector) 通过 CSS 选择器查找元素节点(返回第一个匹配节点) document.querySelector(".box #title")
querySelectorAll(selector) 通过 CSS 选择器查找所有匹配节点(返回 NodeList 类数组) document.querySelectorAll("p.active")
parentNode.children 获取父元素的 "所有子元素节点"(只含元素节点,不含文本 / 注释,常用) div.children → 所有子 <div>/<p>

2. 创建节点

当需要添加新内容时,先创建节点,再插入到 DOM 树中:

方法名 作用 示例
createElement(tag) 创建元素节点(如 <div><button> const newDiv = document.createElement("div")
createTextNode(text) 创建文本节点 const textNode = document.createTextNode("Hello")
createComment(comment) 创建注释节点 const commentNode = document.createComment("新注释")

3. 插入节点

创建节点后,需通过 "父节点" 将其插入到 DOM 树中(否则节点只存在于内存,不显示在页面):

方法名 作用 示例(parent 是父元素,newNode 是新节点,refNode 是参考节点)
parent.appendChild(newNode) 将新节点插入到父节点的 "最后一个子节点" 后面 document.body.appendChild(newDiv)
parent.insertBefore(newNode, refNode) 将新节点插入到 "参考节点 refNode" 的前面 div.insertBefore(newP, div.firstChild)

4. 修改节点

修改已存在的节点(内容、属性、样式等):

  • 修改内容 :用 innerHTML(含标签)或 textContent(纯文本)
    示例:document.querySelector("p").textContent = "修改后的文本"
  • 修改属性 :直接赋值(如 img.src = "new.jpg")或用 setAttribute
    示例:div.setAttribute("class", "new-box")(设置属性)、div.removeAttribute("id")(删除属性)
  • 修改样式 :通过 style 属性操作行内样式(注意 CSS 属性转驼峰,如 backgroundColor
    示例:div.style.color = "red"div.style.fontSize = "16px"

5. 删除节点

通过 "父节点" 删除子节点(不能直接删除自己):

方法名 作用 示例(parent 是父元素,child 是要删除的子节点)
parent.removeChild(child) 删除父节点下的指定子节点 document.body.removeChild(newDiv)
child.remove() (ES6+)直接删除节点(无需通过父节点,更简洁) newDiv.remove()

五、常见误区与注意点

  1. 空白文本节点问题 :HTML 中的换行、空格会被解析为 "文本节点",导致 childNodes 可能包含空白节点。

    示例:<div>\n <p>Hello</p>\n</div> 中,div.childNodes 包含 "换行空格" 文本节点、<p> 元素节点、"换行空格" 文本节点。

    解决:若只需元素节点,用 children 代替 childNodes

  2. nodeListHTMLCollection 的区别

    • 两者都是 "类数组"(需用 Array.from() 转成真正数组才能用 map/filter);
    • nodeList(如 querySelectorAll 返回)包含所有类型节点(元素、文本、注释),HTMLCollection(如 getElementsByClassName 返回)只含元素节点;
    • HTMLCollection 是 "动态的"(文档变化时自动更新),nodeList 是 "静态的"(文档变化不影响)。
  3. innerHTML 的安全风险 :若 innerHTML 赋值的内容来自用户输入(如评论、表单),可能存在 XSS 攻击 (注入恶意脚本)。

    解决:纯文本用 textContent,需解析标签时先过滤恶意代码。

六、实际应用场景示例

通过一个简单案例,串联 DOM 节点的 "查、创、插、改、删" 操作:

html 复制代码
<!-- HTML 结构 -->
<div id="container">
  <p class="title">原标题</p>
</div>
<button id="addBtn">添加内容</button>
<button id="delBtn">删除内容</button>

<script>
// 1. 查找节点
const container = document.getElementById("container");
const addBtn = document.getElementById("addBtn");
const delBtn = document.getElementById("delBtn");

// 2. 点击"添加"按钮:创建并插入节点
addBtn.onclick = function() {
  // 创建元素节点和文本节点
  const newP = document.createElement("p");
  const newText = document.createTextNode("新添加的文本");
  
  // 组装节点(将文本节点插入到 p 中)
  newP.appendChild(newText);
  // 设置 p 的样式和属性
  newP.style.color = "blue";
  newP.className = "content";
  
  // 将 p 插入到 container 中(最后一个子节点后面)
  container.appendChild(newP);
  
  // 同时修改原标题的内容
  document.querySelector(".title").textContent = "修改后的标题";
};

// 3. 点击"删除"按钮:删除最后一个子节点
delBtn.onclick = function() {
  const lastChild = container.lastElementChild; // 只找元素节点
  if (lastChild) { // 确保有子节点可删
    container.removeChild(lastChild);
  }
};
</script>

总结

DOM 节点是网页的 "骨架",所有前端动态交互都基于对节点的操作。核心要点:

  1. 明确 5 种节点类型,重点掌握元素节点文本节点
  2. 熟记通用属性(nodeTypeparentNode)和元素节点专属属性(classNameinnerHTML);
  3. 掌握 "查、创、插、改、删"5 类核心操作,结合实际场景灵活运用;
  4. 注意空白文本节点、类数组转换、XSS 安全等细节问题。
相关推荐
码畜也有梦想2 小时前
springboot响应式编程笔记
java·spring boot·笔记
·白小白2 小时前
C++类(上)默认构造和运算符重载
c++·学习
一只小风华~2 小时前
Vue: ref、reactive、shallowRef、shallowReactive
前端·javascript·vue.js
爱喝水的鱼丶3 小时前
SAP-MM:SAP采购组织全面学习指南:从概念到实战配置图解
运维·开发语言·数据库·学习·sap·mm模块·采购组织
没头脑的男大3 小时前
零碎的嵌入式笔记2
笔记
楼田莉子3 小时前
Python学习——字典和文件
开发语言·python·学习·pycharm
小龙3 小时前
图卷积神经网络(GCN)学习笔记
笔记·学习·cnn·gcn·图卷积神经网络·理论知识
永日456703 小时前
学习日记-CSS-day53-9.11
前端·css·学习
云枫晖3 小时前
JS核心知识-this的指向
前端·javascript