Appearance
DOM 进阶:节点操作
15.1 节点层级:父节点 / 子节点 / 兄弟节点
在 DOM 树中,元素之间存在层级关系,我们可以通过各种属性来访问这些关系。
父节点(Parent Node)
javascript
const child = document.getElementById("child");
const parent = child.parentNode; // 获取父节点
console.log(parent);子节点(Child Nodes)
javascript
const parent = document.getElementById("parent");
// 获取所有子节点(包括文本节点)
const childNodes = parent.childNodes;
console.log(childNodes.length);
// 获取所有子元素(只包括元素节点)
const children = parent.children;
console.log(children.length);
// 获取第一个子元素
const firstChild = parent.firstElementChild;
console.log(firstChild);
// 获取最后一个子元素
const lastChild = parent.lastElementChild;
console.log(lastChild);兄弟节点(Sibling Nodes)
javascript
const element = document.getElementById("element");
// 获取前一个兄弟元素
const previousSibling = element.previousElementSibling;
console.log(previousSibling);
// 获取后一个兄弟元素
const nextSibling = element.nextElementSibling;
console.log(nextSibling);15.2 创建 / 添加 / 删除 / 克隆节点
创建节点
创建元素节点
javascript
// 创建一个 div 元素
const newDiv = document.createElement("div");
newDiv.textContent = "这是一个新创建的 div";
newDiv.className = "new-box";创建文本节点
javascript
// 创建一个文本节点
const textNode = document.createTextNode("这是一段文本");添加节点
appendChild() 方法
将节点添加到父节点的末尾。
javascript
const parent = document.getElementById("parent");
const newDiv = document.createElement("div");
newDiv.textContent = "新添加的元素";
// 添加到父节点末尾
parent.appendChild(newDiv);insertBefore() 方法
在指定节点前插入新节点。
javascript
const parent = document.getElementById("parent");
const referenceNode = document.getElementById("reference");
const newDiv = document.createElement("div");
newDiv.textContent = "插入的元素";
// 在 referenceNode 前插入新节点
parent.insertBefore(newDiv, referenceNode);删除节点
removeChild() 方法
删除指定的子节点。
javascript
const parent = document.getElementById("parent");
const child = document.getElementById("child");
// 删除子节点
parent.removeChild(child);remove() 方法(ES6+)
直接删除节点自身。
javascript
const element = document.getElementById("element");
element.remove();克隆节点
cloneNode() 方法
克隆节点,参数为 true 时会克隆所有子节点,为 false 时只克隆节点本身。
javascript
const original = document.getElementById("original");
// 浅克隆(只克隆节点本身)
const shallowClone = original.cloneNode(false);
// 深克隆(克隆节点及其所有子节点)
const deepClone = original.cloneNode(true);
// 将克隆的节点添加到文档中
const parent = document.getElementById("parent");
parent.appendChild(deepClone);15.3 实战:动态添加列表项 / 删除商品
实战 1:动态添加列表项
html
<!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>
<input type="text" id="inputItem" placeholder="请输入列表项">
<button id="addBtn">添加</button>
<ul id="list"></ul>
<script>
const inputItem = document.getElementById("inputItem");
const addBtn = document.getElementById("addBtn");
const list = document.getElementById("list");
addBtn.addEventListener("click", function() {
const itemText = inputItem.value.trim();
if (itemText) {
// 创建新的 li 元素
const li = document.createElement("li");
// 设置 li 的内容
li.textContent = itemText;
// 创建删除按钮
const deleteBtn = document.createElement("button");
deleteBtn.textContent = "删除";
deleteBtn.style.marginLeft = "10px";
// 添加删除事件
deleteBtn.addEventListener("click", function() {
li.remove();
});
// 将删除按钮添加到 li 中
li.appendChild(deleteBtn);
// 将 li 添加到列表中
list.appendChild(li);
// 清空输入框
inputItem.value = "";
}
});
</script>
</body>
</html>实战 2:删除商品
html
<!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>
.product {
display: flex;
align-items: center;
padding: 10px;
border-bottom: 1px solid #eee;
}
.product-name {
flex: 1;
}
.delete-btn {
background-color: #ff4444;
color: white;
border: none;
padding: 5px 10px;
cursor: pointer;
}
</style>
</head>
<body>
<h2>商品列表</h2>
<div id="productList">
<div class="product">
<div class="product-name">商品 1</div>
<button class="delete-btn">删除</button>
</div>
<div class="product">
<div class="product-name">商品 2</div>
<button class="delete-btn">删除</button>
</div>
<div class="product">
<div class="product-name">商品 3</div>
<button class="delete-btn">删除</button>
</div>
</div>
<script>
const deleteBtns = document.querySelectorAll(".delete-btn");
deleteBtns.forEach(btn => {
btn.addEventListener("click", function() {
// 获取当前按钮所在的商品行
const product = this.parentNode;
// 删除商品行
product.remove();
});
});
</script>
</body>
</html>实战 3:动态创建表格行
html
<!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>
table {
border-collapse: collapse;
width: 100%;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
.add-btn {
margin: 10px 0;
padding: 5px 10px;
}
</style>
</head>
<body>
<button id="addRowBtn" class="add-btn">添加行</button>
<table id="myTable">
<thead>
<tr>
<th>姓名</th>
<th>年龄</th>
<th>操作</th>
</tr>
</thead>
<tbody id="tableBody">
<tr>
<td>张三</td>
<td>25</td>
<td><button class="delete-btn">删除</button></td>
</tr>
<tr>
<td>李四</td>
<td>30</td>
<td><button class="delete-btn">删除</button></td>
</tr>
</tbody>
</table>
<script>
const addRowBtn = document.getElementById("addRowBtn");
const tableBody = document.getElementById("tableBody");
let rowCount = 2;
addRowBtn.addEventListener("click", function() {
rowCount++;
// 创建新行
const row = document.createElement("tr");
// 创建姓名单元格
const nameCell = document.createElement("td");
nameCell.textContent = `用户 ${rowCount}`;
// 创建年龄单元格
const ageCell = document.createElement("td");
ageCell.textContent = 20 + Math.floor(Math.random() * 10);
// 创建操作单元格
const actionCell = document.createElement("td");
const deleteBtn = document.createElement("button");
deleteBtn.textContent = "删除";
deleteBtn.className = "delete-btn";
// 添加删除事件
deleteBtn.addEventListener("click", function() {
row.remove();
});
actionCell.appendChild(deleteBtn);
// 将单元格添加到行中
row.appendChild(nameCell);
row.appendChild(ageCell);
row.appendChild(actionCell);
// 将行添加到表格体中
tableBody.appendChild(row);
});
// 为现有的删除按钮添加事件
document.querySelectorAll(".delete-btn").forEach(btn => {
btn.addEventListener("click", function() {
this.parentNode.parentNode.remove();
});
});
</script>
</body>
</html>节点类型
DOM 中的节点类型有多种,常见的包括:
| 节点类型 | 常量 | 描述 |
|---|---|---|
| 元素节点 | 1 | HTML 元素,如 <div>、<p> 等 |
| 文本节点 | 3 | 元素内的文本内容 |
| 属性节点 | 2 | 元素的属性 |
| 注释节点 | 8 | 注释内容 |
| 文档节点 | 9 | 整个 HTML 文档 |
可以通过 nodeType 属性获取节点类型:
javascript
const element = document.getElementById("myElement");
console.log(element.nodeType); // 输出:1(元素节点)
const text = element.firstChild;
console.log(text.nodeType); // 输出:3(文本节点)小结
- DOM 树中元素之间存在层级关系:父节点、子节点、兄弟节点
- 访问节点关系的属性:
parentNode、children、firstElementChild、lastElementChild、previousElementSibling、nextElementSibling - 创建节点:
createElement()、createTextNode() - 添加节点:
appendChild()、insertBefore() - 删除节点:
removeChild()、remove() - 克隆节点:
cloneNode() - 动态操作节点是实现交互式网页的重要手段,如添加列表项、删除商品等
- 理解节点类型有助于更精确地操作 DOM
