目录
DOM 树、DOM 对象、元素操作
DOM(Document Object Model)是浏览器将 HTML 或 XML 文档解析为 树形结构 的编程接口,开发者可通过 JavaScript 动态操作网页内容、结构和样式。
一、DOM 树与 DOM 对象
DOM 树
定义:浏览器将 HTML 文档解析为 树形结构 的层级模型,每个 HTML 标签、属性、文本都对应树中的节点。
结构:包含根节点(
document
)、元素节点、文本节点、属性节点等。作用:提供编程接口,让 JavaScript 动态操作网页内容。
DOM 对象
定义:DOM 树中的每个节点都是一个 对象,拥有属性和方法。
类型:
Element
:元素节点(如<div>
)。Text
:文本节点。Attr
:属性节点。Document
:整个文档的入口。
DOM 树示例
<!DOCTYPE html>
<html>
<head>
<title>DOM 示例</title>
</head>
<body>
<h1>标题</h1>
<p class="content">段落</p>
</body>
</html>
document
├── html (元素节点)
│ ├── head (元素节点)
│ │ └── title (元素节点)
│ │ └── "DOM 示例" (文本节点)
│ └── body (元素节点)
│ ├── h1 (元素节点)
│ │ └── "标题" (文本节点)
│ └── p (元素节点)
│ ├── class="content" (属性节点)
│ └── "段落" (文本节点)
└── ...
二、获取 DOM 元素
1. 基础方法
方法 | 返回类型 | 示例 |
---|---|---|
document.getElementById() |
单个元素 | document.getElementById("box") |
document.getElementsByClassName() |
HTMLCollection(动态) | document.getElementsByClassName("item") |
document.getElementsByTagName() |
HTMLCollection(动态) | document.getElementsByTagName("div") |
2. 现代方法(ES6+)
方法 | 返回类型 | 示例 |
---|---|---|
document.querySelector() |
单个元素 | document.querySelector(".container") |
document.querySelectorAll() |
NodeList(静态) | document.querySelectorAll("li") |
区别:
动态集合(如
HTMLCollection
):元素变化时自动更新。const items = document.getElementsByClassName("item"); console.log(items.length); // 假设初始为 2 document.body.appendChild(document.createElement("div")); // 动态集合长度自动更新 console.log(items.length); // 3
静态集合(如
NodeList
):查询后不再更新。const list = document.querySelectorAll("li"); console.log(list.length); // 假设初始为 3 document.body.appendChild(document.createElement("li")); console.log(list.length); // 仍为 3
三、修改元素内容
属性/方法 | 说明 | 示例 |
---|---|---|
innerHTML |
获取或设置元素的 HTML 内容(解析标签) | element.innerHTML = "<b>加粗</b>" |
textContent |
获取或设置元素的文本内容(不解析标签) | element.textContent = "纯文本" |
innerText |
获取可见文本(考虑样式,性能较低) | element.innerText = "可见文本" |
注意:
innerHTML
可能引发 XSS 攻击(避免插入未经验证的用户输入)。textContent
性能优于innerText
。
四、修改元素常见属性
方法 | 说明 | 示例 |
---|---|---|
getAttribute() |
获取属性值 | element.getAttribute("href") |
setAttribute() |
设置属性值 | element.setAttribute("class", "active") |
removeAttribute() |
删除属性 | element.removeAttribute("disabled") |
直接访问属性 | 通过元素属性名快速访问(部分属性需特殊处理) | element.id = "newId" |
1. 标准属性
直接通过 DOM 对象属性操作:
element.id = "newId"; // 修改 id
element.className = "active"; // 修改 class(覆盖原有类)
element.href = "https://example.com"; // 修改链接
2. 通用方法
element.setAttribute("属性名", "值"); // 设置属性
element.getAttribute("属性名"); // 获取属性
element.removeAttribute("属性名"); // 删除属性
示例:
const img = document.querySelector("img");
img.setAttribute("src", "new-image.jpg");
img.removeAttribute("alt");
五、通过 style
修改样式
方法 | 说明 | 示例 |
---|---|---|
style 属性 |
修改内联样式 | element.style.color = "red" |
classList |
操作类名(添加、删除、切换) | element.classList.add("active") |
window.getComputedStyle() |
获取最终计算的样式(包括外部 CSS) | getComputedStyle(element).fontSize |
直接操作元素的 style
属性(修改内联样式):
element.style.color = "red"; // 单个样式
element.style.backgroundColor = "#fff"; // 驼峰命名
element.style.cssText = "color: red; font-size: 16px;"; // 批量设置
注意:
修改
style
只影响内联样式,优先级高于外部 CSS。频繁操作
style
可能触发重绘(性能敏感时需优化)。
六、通过类名修改样式
1. className
属性
直接覆盖所有类名:
element.className = "class1 class2"; // 覆盖原有类
2. classList
方法(推荐)
精细控制类名:
element.classList.add("new-class"); // 添加类
element.classList.remove("old-class"); // 删除类
element.classList.toggle("active"); // 切换类(存在则删除,否则添加)
element.classList.contains("active"); // 检查是否包含类
优势:
避免覆盖其他类名。
支持链式调用:
element.classList.add("a").remove("b")
。
七、获取和设置表单的值
1. 输入框(input
、textarea
)
const input = document.querySelector("input");
// 获取值
console.log(input.value);
// 设置值
input.value = "新内容";
2. 单选/复选框(radio
、checkbox
)
const checkbox = document.querySelector("input[type=checkbox]");
// 获取选中状态
console.log(checkbox.checked); // true/false
// 设置选中状态
checkbox.checked = true;
3. 下拉框(select
)
const select = document.querySelector("select");
// 获取选中值
console.log(select.value);
// 设置选中值
select.value = "option2";
八、自定义属性(data-*
)
1. 定义与访问
HTML 中定义自定义属性:
<div id="user" data-id="123" data-user-name="Alice"></div>
JavaScript 通过 dataset
访问:
const user = document.getElementById("user");
console.log(user.dataset.id); // "123"
console.log(user.dataset.userName); // "Alice"(驼峰命名转换)
2. 修改自定义属性
user.dataset.id = "456"; // 修改 data-id
user.dataset.userRole = "admin"; // 添加 data-user-role
delete user.dataset.userName; // 删除 data-user-name
注意:
属性名需符合
data-*
格式。dataset
会自动将短横线命名转为驼峰式(如data-user-name
→userName
)。
示例:全选反选案例
<body>
<table>
<tr>
<th class="allCheck">
<input type="checkbox" name="" id="checkAll"> <span class="all">全选</span>
</th>
<th>商品</th>
<th>商家</th>
<th>价格</th>
</tr>
<tr>
<td>
<input type="checkbox" name="check" class="ck">
</td>
<td>小米手机</td>
<td>小米</td>
<td>¥1999</td>
</tr>
<tr>
<td>
<input type="checkbox" name="check" class="ck">
</td>
<td>小米净水器</td>
<td>小米</td>
<td>¥4999</td>
</tr>
<tr>
<td>
<input type="checkbox" name="check" class="ck">
</td>
<td>小米电视</td>
<td>小米</td>
<td>¥5999</td>
</tr>
</table>
<script>
const checkAll = document.querySelector('#checkAll')
const checks = document.querySelectorAll('.ck')
checkAll.addEventListener('click', function () {
for (let i = 0; i < checks.length; i++) {
checks[i].checked = checkAll.checked
}
})
for (let i = 0; i < checks.length; i++) {
checks[i].addEventListener('click', function () {
checkAll.checked = document.querySelectorAll('.ck:checked').length === checks.length
})
}
</script>
</body>