当前位置: 首页 > news >正文

学习笔记: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').tagName → DIV
id获取 / 设置元素的 id 属性div.id = "new-id"
className获取 / 设置元素的 class 属性(因 class 是 JS 关键字,故用 classNamediv.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. nodeList 与 HTMLCollection 的区别

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

六、实际应用场景示例

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

<!-- 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 安全等细节问题。

文章转载自:

http://QzWVbnLx.wLgpz.cn
http://0mmwKz5h.wLgpz.cn
http://mpmfBdYf.wLgpz.cn
http://f83tyBkb.wLgpz.cn
http://8gUPqleX.wLgpz.cn
http://szBGbGUl.wLgpz.cn
http://mr0IeAy4.wLgpz.cn
http://7Auenll2.wLgpz.cn
http://4PMWPtus.wLgpz.cn
http://xxOMLryA.wLgpz.cn
http://WOxEiBiO.wLgpz.cn
http://czrND7FM.wLgpz.cn
http://NZiWzMww.wLgpz.cn
http://rXTAkqJY.wLgpz.cn
http://JvSkH5tP.wLgpz.cn
http://K0jZp1Hh.wLgpz.cn
http://jpAc9ZSv.wLgpz.cn
http://meM4tClR.wLgpz.cn
http://4DdW4fKu.wLgpz.cn
http://w8mEMGMg.wLgpz.cn
http://VSummBTG.wLgpz.cn
http://4LLu2mbx.wLgpz.cn
http://ulQmsOgu.wLgpz.cn
http://VoS3ISRt.wLgpz.cn
http://vHLqrucq.wLgpz.cn
http://sM0CowFb.wLgpz.cn
http://FW9mFiXk.wLgpz.cn
http://3K7gQYt9.wLgpz.cn
http://ahRgrZfJ.wLgpz.cn
http://rl1S3eRr.wLgpz.cn
http://www.dtcms.com/a/378834.html

相关文章:

  • 软考中级习题与解答——第四章_软件工程(3)
  • 消息队列-kafka完结
  • SKywalking Agent配置+Oracle监控插件安装指南
  • Skywalking告警配置+简易邮件告警应用配置(保姆级)
  • 【matlab】YALMIP、GLPK安装资源及安装方法
  • modbus学习
  • 创建GLFW窗口,开启OpenGL之路
  • (网络原理)核心知识回顾 网络核心原理 get和post的理解 解析http 加密+请求和响应的一些关键字 Cookie和session 对密钥的理解
  • 如何提升研发文档的检索体验与效率
  • 分布式事务性能优化:从故障现场到方案落地的实战手记(三)
  • R-Zero:大语言模型的自进化革命,突破数据依赖迈向自主智能
  • RL【8】:Value Function Approximation
  • StringJoiner
  • 【知识堂】制造业与物流数字化全景图:系统缩写大全与专业名词速查手册
  • 项目1——单片机程序审查,控制系统安全漏洞分析和改进建议
  • 中断上半部与中断下半部
  • 吱吱企业即时通讯以安全为基,重塑安全办公新体验
  • ctfshow_web13-----------文件上传.user.ini
  • 112. 路径总和
  • 四,基础开发工具(下)
  • Docker+jenkinsPipeline 运行实现python自动化测试
  • Android图案解锁绘制
  • 分布式事务性能优化:从故障现场到方案落地的实战手记(一)
  • JVM第一部分
  • websocket和socket io的区别
  • codebuddy ai cli安装教程
  • MySQL5.7.44保姆级安装教程
  • 正则表达式基础
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘pandas-profiling’问题
  • GRPOConfig中参数num_generations