DOM(文档对象模型)是 JavaScript 操作网页内容的核心接口,而节点操作则是 DOM 编程的基础,是蓝桥杯 Web 应用开发赛道的必考核心考点,无论是动态交互效果、数据渲染还是功能实现,都离不开节点的获取、增删、修改与遍历。
一、DOM 节点基础认知与核心类型
HTML 文档中的所有内容,在 DOM 树中都以「节点」的形式存在。整个文档是一个文档节点,每个 HTML 标签是元素节点,标签内的文本是文本节点,HTML 注释是注释节点,节点之间形成父子、兄弟的层级关系。
1.1 核心节点类型(蓝桥杯高频辨析考点)
代码中提到的「换行、空格是文本节点」「注释节点」,是新手最容易踩坑的点,也是蓝桥杯选择题、实操题的高频细节考点。DOM 核心节点类型如下:
|------|--------------------------|-------------------------------------|------------------|
| 节点类型 | 对应属性 | 说明 | 常见场景 |
| 元素节点 | Node.ELEMENT_NODE | HTML 标签对应的节点,如<div>、<p>,是最常用的节点 | 页面所有可见的标签元素 |
| 文本节点 | Node.TEXT_NODE | 标签内的文本内容,包括换行、空格、缩进 | 两个标签之间的换行、标签内的文字 |
| 注释节点 | Node.COMMENT_NODE | HTML 注释内容,即<!-- 注释 --> | 代码中的注释标记 |
| 文档节点 | Node.DOCUMENT_NODE | 整个文档对象,即document | DOM 树的根节点 |
1.2 核心辨析:节点集合 childNodes 与 children
这是代码中重点演示的内容,也是蓝桥杯必考的辨析点,二者核心区别如下:
-
childNodes:获取元素的所有子节点 ,包括元素节点、文本节点、注释节点,返回NodeList集合 -
children:获取元素的所有元素子节点 ,仅包含HTML标签节点,返回HTMLCollection集合
1.3 代码实例:节点类型与集合区分演示
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>节点类型与集合演示</title>
</head>
<body>
<div class="father">
<div class="child1">111</div>
<div class="child2">222</div>
<div class="cc1"></div>
<div class="cc2"></div>
<div class="child3">333</div>
<div class="child4">444</div>
<!-- 这是注释节点 -->
</div>
<script>
const father = document.querySelector('.father');
// 1. 获取所有子节点(包含文本、注释)
console.log('所有子节点 childNodes:', father.childNodes);
// 2. 仅获取元素子节点
console.log('仅元素子节点 children:', father.children);
// 3. 查看节点类型
console.log('第一个节点类型(换行文本节点):', father.firstChild.nodeType);
console.log('第一个元素节点类型:', father.firstElementChild.nodeType);
</script>
</body>
</html>
考点提示:蓝桥杯实操题中,若需要遍历子元素修改样式/内容,必须使用
children而非childNodes,否则会获取到换行、注释等非元素节点,导致代码报错或效果异常。
二、DOM 节点获取核心API
节点获取是所有DOM操作的前提,代码中演示了父子、兄弟节点的全量获取方式,分为基础选择器获取、层级关系获取两大类,均为蓝桥杯必考内容。
2.1 基础选择器获取
最常用的节点获取方式,支持CSS选择器,精准定位目标元素:
-
querySelector(selector):获取匹配选择器的第一个元素节点 -
querySelectorAll(selector):获取匹配选择器的所有 元素节点,返回NodeList集合
2.2 层级关系获取(父子/兄弟节点)
基于当前节点的相对位置获取关联节点,是蓝桥杯动态交互题的高频考点,核心API分为父子、兄弟两类。
(1)父子节点获取
|-------------------------|----------------------|--------|----------------------|
| API | 说明 | 返回值类型 | 注意事项(考点) |
| parentElement | 获取当前节点的父元素节点 | 单个元素节点 | 仅返回元素节点,无父节点返回null |
| firstChild | 获取当前节点的第一个子节点 | 单个节点 | 可能返回文本/注释节点(换行、空格) |
| firstElementChild | 获取当前节点的第一个元素子节点 | 单个元素节点 | 仅返回元素节点,蓝桥杯实操首选 |
| lastChild | 获取当前节点的最后一个子节点 | 单个节点 | 可能返回文本/注释节点 |
| lastElementChild | 获取当前节点的最后一个元素子节点 | 单个元素节点 | 仅返回元素节点,无兼容问题 |
(2)兄弟节点获取
|------------------------------|----------------------|--------|---------------------|
| API | 说明 | 返回值类型 | 注意事项(考点) |
| nextElementSibling | 获取当前节点的下一个兄弟元素节点 | 单个元素节点 | 仅返回元素节点,无则返回null |
| previousElementSibling | 获取当前节点的上一个兄弟元素节点 | 单个元素节点 | 仅返回元素节点,无则返回null |
| nextSibling | 获取当前节点的下一个兄弟节点 | 单个节点 | 可能返回文本/注释节点,不推荐实操使用 |
| previousSibling | 获取当前节点的上一个兄弟节点 | 单个节点 | 可能返回文本/注释节点,不推荐实操使用 |
2.3 节点获取API汇总表
|-------|------------------------------|-------------|----------|
| 分类 | API | 核心作用 | 蓝桥杯考点优先级 |
| 基础选择器 | querySelector() | 精准获取单个元素 | ⭐⭐⭐⭐⭐ |
| 基础选择器 | querySelectorAll() | 获取匹配的所有元素 | ⭐⭐⭐⭐⭐ |
| 父子节点 | parentElement | 获取父元素节点 | ⭐⭐⭐⭐ |
| 父子节点 | children | 获取所有元素子节点 | ⭐⭐⭐⭐⭐ |
| 父子节点 | firstElementChild | 获取第一个元素子节点 | ⭐⭐⭐⭐ |
| 父子节点 | lastElementChild | 获取最后一个元素子节点 | ⭐⭐⭐⭐ |
| 兄弟节点 | nextElementSibling | 获取下一个兄弟元素 | ⭐⭐⭐⭐ |
| 兄弟节点 | previousElementSibling | 获取上一个兄弟元素 | ⭐⭐⭐⭐ |
2.4 代码实例:层级节点获取完整演示
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>层级节点获取演示</title>
<style>
.active { color: red; font-weight: bold; }
</style>
</head>
<body>
<div class="father">
<div class="child1">111</div>
<div class="child2">222</div>
<div class="cc1">目标元素</div>
<div class="cc2">444</div>
<div class="child3">555</div>
<div class="child4">666</div>
</div>
<script>
// 获取目标元素
const cc1 = document.querySelector('.cc1');
// 1. 获取父节点
const father = cc1.parentElement;
console.log('父元素:', father);
// 2. 通过父节点获取第一个子元素
const firstChild = father.firstElementChild;
console.log('第一个子元素:', firstChild);
firstChild.classList.add('active');
// 3. 获取最后一个子元素
const lastChild = father.lastElementChild;
console.log('最后一个子元素:', lastChild);
// 4. 获取上一个兄弟元素
const prevSibling = cc1.previousElementSibling;
console.log('上一个兄弟元素:', prevSibling);
// 5. 获取下一个兄弟元素
const nextSibling = cc1.nextElementSibling;
console.log('下一个兄弟元素:', nextSibling);
nextSibling.style.color = 'blue';
</script>
</body>
</html>
三、DOM 节点的增删改操作(蓝桥杯实操核心考点)
节点的创建、添加、删除、修改是动态网页的核心,也是蓝桥杯Web赛道实操题的必考内容,几乎所有功能题都需要用到相关API,代码中演示了核心的创建、添加、删除操作,下面进行系统梳理与拓展。
3.1 节点创建
创建新的元素节点是动态添加内容的前提,核心方式有两种:
-
document.createElement(tagName):创建一个新的元素节点,是W3C标准推荐的方式,安全性高,无XSS风险 -
innerHTML:通过HTML字符串直接创建节点,写法简洁,但存在XSS安全风险,蓝桥杯实操中需谨慎使用
3.2 节点添加
将创建好的节点添加到DOM树中,才能在页面中显示,核心API如下:
|-------------------------|-------------------|-----------|----------|
| API | 作用 | 插入位置 | 蓝桥杯考点优先级 |
| appendChild(node) | 将节点添加到父元素的子节点列表末尾 | 父元素内部的最后 | ⭐⭐⭐⭐⭐ |
| prepend(node) | 将节点添加到父元素的子节点列表开头 | 父元素内部的最前 | ⭐⭐⭐⭐⭐ |
| before(node) | 将节点添加到当前元素的前面 | 当前元素的同级之前 | ⭐⭐⭐⭐ |
| after(node) | 将节点添加到当前元素的后面 | 当前元素的同级之后 | ⭐⭐⭐⭐ |
考点坑点提示:同一个DOM节点在文档中是唯一的 。代码中同时执行
appendChild(child)和prepend(child),不会添加两个节点,只会将节点从末尾移动到开头,这是蓝桥杯高频易错点。若需要添加多个相同节点,需使用cloneNode()克隆节点。
3.3 节点删除
移除页面中的节点,核心API有两种:
|--------------------------------|------------|------------------------------|--------------------|
| API | 作用 | 用法 | 考点提示 |
| node.remove() | 直接删除当前节点 | child1.remove() | 写法简洁,蓝桥杯实操首选,无兼容问题 |
| parent.removeChild(node) | 通过父节点删除子节点 | father.removeChild(child1) | 传统写法,需先获取父节点 |
3.4 拓展操作:节点替换与克隆
蓝桥杯进阶考点,常用于批量渲染、节点复制场景:
-
replaceChild(newNode, oldNode):用新节点替换旧节点 -
cloneNode(deep):克隆节点,deep=true为深克隆(克隆节点及所有子节点),deep=false为浅克隆(仅克隆节点本身)
3.5 节点增删改API汇总表
|------|--------------------------------|------------|-------------------------|
| 操作类型 | API | 核心作用 | 必记参数/注意事项 |
| 创建节点 | document.createElement() | 创建新的元素节点 | 参数为标签名,如'div'、'li' |
| 添加节点 | appendChild() | 父元素末尾添加节点 | 参数为要添加的节点对象 |
| 添加节点 | prepend() | 父元素开头添加节点 | 参数为要添加的节点对象 |
| 添加节点 | before() / after() | 同级前后添加节点 | 参数为要添加的节点对象 |
| 删除节点 | remove() | 直接删除当前节点 | 无参数,直接调用 |
| 删除节点 | removeChild() | 通过父节点删除子节点 | 参数为要删除的子节点 |
| 替换节点 | replaceChild() | 新节点替换旧节点 | 参数:(新节点, 旧节点) |
| 克隆节点 | cloneNode() | 复制节点 | 参数:true深克隆,false浅克隆 |
3.6 代码实例:节点增删改完整功能演示
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>节点增删改演示</title>
<style>
.add, .remove {
width: 200px;
height: 40px;
line-height: 40px;
text-align: center;
background-color: aqua;
border-radius: 10px;
color: #fff;
margin: 10px;
cursor: pointer;
display: inline-block;
}
.father {
margin: 20px;
border: 1px solid #333;
padding: 10px;
}
.father div {
margin: 5px 0;
padding: 5px;
background-color: #f5f5f5;
}
</style>
</head>
<body>
<div class="father">
<div class="child1">111</div>
<div class="child2">222</div>
<div class="cc1"></div>
<div class="cc2"></div>
<div class="child3">333</div>
<div class="child4">444</div>
</div>
<div class="add" onclick="addChild()">添加新节点</div>
<div class="remove" onclick="removeFirstChild()">删除第一个节点</div>
<script>
const father = document.querySelector('.father');
const child1 = document.querySelector('.child1');
// 添加节点函数
function addChild() {
// 1. 创建新节点
const newChild = document.createElement('div');
// 2. 设置节点内容与样式
newChild.innerHTML = '新创建的节点';
newChild.style.color = 'red';
// 3. 添加到父元素末尾(若要添加到开头,使用father.prepend(newChild))
father.appendChild(newChild);
}
// 删除节点函数
function removeFirstChild() {
// 获取第一个元素子节点
const firstChild = father.firstElementChild;
// 存在节点才执行删除,避免报错
if (firstChild) {
firstChild.remove();
}
}
</script>
</body>
</html>
四、蓝桥杯 Web 考点实战
蓝桥杯 Web 应用开发赛道中,DOM 节点操作是基础必考题,常结合交互事件、样式修改、数据渲染出题,核心考察「动态增删」「节点遍历」「层级联动」三大能力,以下是3个高频考点的实战案例。
4.1 考点1:动态列表增删(最高频实操题)
题目要求
实现一个待办列表功能:
-
点击「添加」按钮,将输入框内容作为新列表项添加到列表末尾
-
点击列表项后的「删除」按钮,删除对应的列表项
-
输入框为空时不允许添加,添加后清空输入框
代码实现
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>蓝桥杯考点:动态待办列表</title>
<style>
.container {
width: 400px;
margin: 50px auto;
}
.input-box {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
#todoInput {
flex: 1;
height: 36px;
padding: 0 10px;
border: 1px solid #ccc;
border-radius: 4px;
}
#addBtn {
width: 80px;
height: 36px;
background-color: #2196f3;
color: #fff;
border: none;
border-radius: 4px;
cursor: pointer;
}
.todo-list {
list-style: none;
padding: 0;
margin: 0;
}
.todo-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
border: 1px solid #eee;
border-radius: 4px;
margin-bottom: 10px;
}
.delete-btn {
background-color: #f44336;
color: #fff;
border: none;
border-radius: 4px;
padding: 4px 8px;
cursor: pointer;
}
</style>
</head>
<body>
<div class="container">
<div class="input-box">
<input type="text" id="todoInput" placeholder="请输入待办事项">
<button id="addBtn">添加</button>
</div>
<ul class="todo-list" id="todoList"></ul>
</div>
<script>
// 获取元素
const todoInput = document.getElementById('todoInput');
const addBtn = document.getElementById('addBtn');
const todoList = document.getElementById('todoList');
// 添加待办
addBtn.addEventListener('click', () => {
const content = todoInput.value.trim();
// 非空校验
if (!content) return;
// 1. 创建列表项节点
const li = document.createElement('li');
li.className = 'todo-item';
// 2. 设置内容
li.innerHTML = `
<span>${content}</span>
<button class="delete-btn">删除</button>
`;
// 3. 添加到列表
todoList.appendChild(li);
// 4. 清空输入框
todoInput.value = '';
// 给删除按钮绑定事件
const deleteBtn = li.querySelector('.delete-btn');
deleteBtn.addEventListener('click', () => {
li.remove();
});
});
// 回车添加
todoInput.addEventListener('keyup', (e) => {
if (e.key === 'Enter') {
addBtn.click();
}
});
</script>
</body>
</html>
考点解析
本题考察了createElement节点创建、appendChild节点添加、remove节点删除、事件绑定,是蓝桥杯Web赛道最经典的基础实操题,分值占比高,必须熟练掌握。
4.2 考点2:节点遍历与批量样式修改
题目要求
-
获取父容器下的所有子元素节点
-
遍历所有子元素,给奇数项设置红色背景,偶数项设置蓝色背景
-
给第三个子元素添加加粗字体样式
代码实现
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>蓝桥杯考点:节点遍历</title>
<style>
.father {
width: 300px;
margin: 50px auto;
}
.father div {
height: 40px;
line-height: 40px;
padding: 0 10px;
margin: 5px 0;
color: #fff;
border-radius: 4px;
}
</style>
</head>
<body>
<div class="father">
<div>第1项</div>
<div>第2项</div>
<div>第3项</div>
<div>第4项</div>
<div>第5项</div>
<div>第6项</div>
</div>
<script>
const father = document.querySelector('.father');
// 获取所有元素子节点(考点:必须用children,不能用childNodes)
const children = father.children;
// 遍历节点
for (let i = 0; i < children.length; i++) {
const item = children[i];
// 奇偶项设置背景
if (i % 2 === 0) {
// 奇数项(索引从0开始)
item.style.backgroundColor = '#f44336';
} else {
// 偶数项
item.style.backgroundColor = '#2196f3';
}
// 第三个元素(索引2)加粗
if (i === 2) {
item.style.fontWeight = 'bold';
item.style.fontSize = '18px';
}
}
</script>
</body>
</html>
考点解析
本题核心考察children属性的使用、节点遍历,蓝桥杯常以此为基础,结合数据渲染、表格隔行变色等场景出题,重点注意children和childNodes的区别,避免遍历到非元素节点。
4.3 考点3:父子兄弟节点联动交互
题目要求
-
点击任意子元素,给该元素添加激活样式,其余兄弟元素移除激活样式
-
点击子元素时,修改父元素的背景色
-
点击子元素时,获取其前后兄弟元素的内容并打印
代码实现
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>蓝桥杯考点:节点联动</title>
<style>
.father {
width: 400px;
margin: 50px auto;
padding: 20px;
border: 2px solid #333;
border-radius: 8px;
transition: background-color 0.3s;
}
.item {
height: 40px;
line-height: 40px;
padding: 0 10px;
margin: 10px 0;
background-color: #f5f5f5;
border-radius: 4px;
cursor: pointer;
transition: all 0.3s;
}
.item.active {
background-color: #ff9800;
color: #fff;
transform: translateX(10px);
}
</style>
</head>
<body>
<div class="father">
<div class="item">选项1</div>
<div class="item">选项2</div>
<div class="item">选项3</div>
<div class="item">选项4</div>
<div class="item">选项5</div>
</div>
<script>
const father = document.querySelector('.father');
const items = document.querySelectorAll('.item');
// 给每个选项绑定点击事件
items.forEach(item => {
item.addEventListener('click', () => {
// 1. 兄弟元素联动:移除所有激活样式,给当前元素添加
items.forEach(i => i.classList.remove('active'));
item.classList.add('active');
// 2. 父子联动:修改父元素背景色
father.style.backgroundColor = '#fff3e0';
// 3. 获取兄弟节点
const prev = item.previousElementSibling;
const next = item.nextElementSibling;
console.log('当前元素:', item.textContent);
console.log('上一个兄弟:', prev ? prev.textContent : '无');
console.log('下一个兄弟:', next ? next.textContent : '无');
});
});
</script>
</body>
</html>
考点解析
本题考察了previousElementSibling、nextElementSibling兄弟节点获取,parentElement父节点操作,以及节点的样式修改,是蓝桥杯交互类题目的高频考点,常结合tab切换、选项卡等场景出题。
五、总结
本文结合示例代码,系统梳理了DOM节点操作的全量核心知识点,覆盖节点认知、获取、增删改全流程,同时结合蓝桥杯Web应用开发赛道的高频考点进行实战演练,核心总结如下:
-
基础认知 :明确元素节点、文本节点、注释节点的区别,牢记
childNodes与children的核心差异,这是蓝桥杯选择题的高频考点。 -
节点获取 :优先使用
querySelector/querySelectorAll精准定位元素,层级获取优先使用带Element的API(如firstElementChild),避免获取到非元素节点。 -
增删改操作 :熟练掌握
createElement创建、appendChild/prepend添加、remove删除三大核心API,注意节点的唯一性,避免出现只移动不添加的bug。 -
蓝桥杯备考技巧:重点练习「动态列表增删」「节点遍历」「层级联动」三大题型,实操中优先使用标准API,注意边界判断(如删除前判断节点是否存在),保证代码的健壮性。
不常用操作:克隆节点
