1.4 DOM 操作
DOM(Document Object Model,文档对象模型)是 HTML 文档的编程接口,JavaScript 通过 DOM 与 HTML 页面进行交互。
一、DOM 概述
什么是 DOM
DOM 是 HTML 文档的树状结构表示,JavaScript 可以通过 DOM 访问和修改页面内容。
HTML 文档
└── 文档节点(document)
└── html 元素
├── head 元素
│ ├── title 元素
│ └── ...
└── body 元素
├── div 元素
├── p 元素
└── ...DOM 节点类型
- 文档节点:document(整个文档的根节点)
- 元素节点:HTML 标签(
<div>、<p>等) - 文本节点:元素内的文本内容
- 属性节点:元素的属性(id、class 等)
- 注释节点:HTML 注释
二、获取元素
1. 根据选择器获取(推荐)
javascript
// querySelector:获取匹配的第一个元素
const element = document.querySelector("#id");
const element = document.querySelector(".class");
const element = document.querySelector("div");
const element = document.querySelector("div.active");
// querySelectorAll:获取匹配的所有元素(NodeList)
const elements = document.querySelectorAll(".class");
const elements = document.querySelectorAll("ul li");2. 根据ID获取
javascript
const element = document.getElementById("id");
// 返回单个元素或 null3. 根据类名获取
javascript
const elements = document.getElementsByClassName("class");
// 返回 HTMLCollection(动态集合)4. 根据标签名获取
javascript
const elements = document.getElementsByTagName("div");
const elements = document.getElementsByTagName("div")[0];
// 返回 HTMLCollection5. 根据name属性获取
javascript
const elements = document.getElementsByName("username");
// 常用于表单元素三、修改元素内容
1. 修改文本内容
javascript
const element = document.querySelector("div");
// innerText(只获取/设置可见文本)
console.log(element.innerText);
element.innerText = "新的文本";
// textContent(获取/设置所有文本,包括隐藏的)
console.log(element.textContent);
element.textContent = "新的文本";2. 修改 HTML 内容
javascript
const element = document.querySelector("div");
// 获取/设置 HTML
console.log(element.innerHTML);
element.innerHTML = "<p>新的内容</p>";
// 设置纯文本(避免 XSS)
element.textContent = "<p>转义过的文本</p>";
// 插入 HTML
element.innerHTML += "<span>添加的元素</span>";四、修改元素属性
1. 标准属性
javascript
const element = document.querySelector("img");
// 获取属性
const src = element.src;
const id = element.id;
const className = element.className;
// 设置属性
element.src = "new-image.jpg";
element.id = "new-id";
element.className = "new-class";
// classList(推荐)
element.classList.add("active");
element.classList.remove("active");
element.classList.toggle("active");
element.classList.contains("active");
element.className; // "active" 或 ""2. 自定义属性
javascript
const element = document.querySelector("div");
// data- 属性
element.setAttribute("data-id", "123");
const dataId = element.getAttribute("data-id");
// dataset(推荐)
element.dataset.id = "123";
console.log(element.dataset.id); // "123"
element.dataset.userName = "张三";
console.log(element.dataset.userName); // "张三"3. style 属性
javascript
const element = document.querySelector("div");
// 设置样式
element.style.color = "red";
element.style.fontSize = "20px";
element.style.backgroundColor = "#f0f0f0";
// 获取样式
console.log(element.style.color); // "red"
// 注意:style 只能获取/设置内联样式
const computedStyle = window.getComputedStyle(element);
console.log(computedStyle.color); // 获取计算后的样式五、创建和插入元素
1. 创建元素
javascript
// 创建元素节点
const div = document.createElement("div");
const p = document.createElement("p");
const img = document.createElement("img");
// 创建文本节点
const text = document.createTextNode("这是一段文本");
// 创建文档片段(减少重排)
const fragment = document.createDocumentFragment();2. 添加内容
javascript
const div = document.createElement("div");
// 设置文本
div.textContent = "标题";
// 设置 HTML
div.innerHTML = "<span>内容</span>";
// 添加文本节点
const text = document.createTextNode("文本");
div.appendChild(text);3. 添加到页面
javascript
const parent = document.querySelector("container");
const child = document.createElement("div");
child.textContent = "子元素";
// appendChild(添加到最后)
parent.appendChild(child);
// prepend(添加到最前)
parent.prepend(child);
// insertBefore(指定位置插入)
const refElement = document.querySelector(".ref");
parent.insertBefore(child, refElement);
// insertAdjacentElement(灵活插入)
const element = document.createElement("div");
element.textContent = "新元素";
parent.insertAdjacentElement("beforebegin", element); // 在父元素之前
parent.insertAdjacentElement("afterbegin", element); // 在父元素第一个子元素之前
parent.insertAdjacentElement("beforeend", element); // 在父元素之后
parent.insertAdjacentElement("afterend", element); // 在父元素最后一个子元素之后4. 替换和删除
javascript
const parent = document.querySelector("container");
const oldElement = document.querySelector(".old");
const newElement = document.createElement("div");
newElement.textContent = "新元素";
// 替换元素
parent.replaceChild(newElement, oldElement);
// 删除元素
oldElement.remove(); // 推荐方式
// parent.removeChild(oldElement); // 旧方式六、节点关系
javascript
const element = document.querySelector("div");
// 父节点
console.log(element.parentNode);
console.log(element.parentElement); // 只返回元素节点
// 子节点
console.log(element.childNodes); // 所有子节点(包括文本节点)
console.log(element.children); // 只获取元素子节点
// 首尾子节点
console.log(element.firstChild); // 第一个节点(可能是文本节点)
console.log(element.firstElementChild); // 第一个元素节点
console.log(element.lastChild); // 最后一个节点
console.log(element.lastElementChild); // 最后一个元素节点
// 兄弟节点
console.log(element.previousSibling); // 上一个兄弟节点
console.log(element.previousElementSibling); // 上一个兄弟元素节点
console.log(element.nextSibling); // 下一个兄弟节点
console.log(element.nextElementSibling); // 下一个兄弟元素节点七、事件处理
1. 监听事件
javascript
const button = document.querySelector("button");
// addEventListener(推荐,可添加多个监听器)
button.addEventListener("click", function() {
console.log("点击了按钮");
});
// 箭头函数
button.addEventListener("click", () => {
console.log("箭头函数");
});
// 命名函数(可移除)
function handleClick() {
console.log("命名函数");
}
button.addEventListener("click", handleClick);
// 事件对象
button.addEventListener("click", function(event) {
console.log(event.type); // 事件类型
console.log(event.target); // 触发元素
console.log(event.currentTarget); // 绑定元素
});2. 移除事件监听
javascript
button.removeEventListener("click", handleClick);3. 事件冒泡与捕获
javascript
// 默认:冒泡(从内到外)
// 捕获:从外到内
// 冒泡阶段处理
element.addEventListener("click", handler, false);
// 捕获阶段处理
element.addEventListener("click", handler, true);
// 阻止冒泡
element.addEventListener("click", function(event) {
event.stopPropagation();
});4. 常用事件类型
javascript
const element = document.querySelector("div");
// 鼠标事件
element.addEventListener("click", () => {}); // 点击
element.addEventListener("dblclick", () => {}); // 双击
element.addEventListener("mousedown", () => {}); // 鼠标按下
element.addEventListener("mouseup", () => {}); // 鼠标松开
element.addEventListener("mouseenter", () => {}); // 鼠标进入
element.addEventListener("mouseleave", () => {}); // 鼠标离开
element.addEventListener("mousemove", () => {}); // 鼠标移动
// 键盘事件
window.addEventListener("keydown", (e) => {
console.log(e.key); // 按键名称
console.log(e.keyCode); // 按键代码
});
window.addEventListener("keyup", () => {});
window.addEventListener("keypress", () => {});
// 表单事件
const input = document.querySelector("input");
input.addEventListener("input", () => {}); // 输入
input.addEventListener("change", () => {}); // 改变
input.addEventListener("focus", () => {}); // 获得焦点
input.addEventListener("blur", () => {}); // 失去焦点
// 文档事件
window.addEventListener("load", () => {}); // 页面加载完成
window.addEventListener("DOMContentLoaded", () => {}); // DOM 加载完成
window.addEventListener("scroll", () => {}); // 滚动
window.addEventListener("resize", () => {}); // 调整窗口大小八、表单操作
1. 获取表单元素
javascript
const form = document.querySelector("form");
const input = document.querySelector("input[type='text']");
const select = document.querySelector("select");
const textarea = document.querySelector("textarea");
const checkbox = document.querySelector("input[type='checkbox']");
const radio = document.querySelector("input[type='radio']");2. 获取/设置值
javascript
const input = document.querySelector("input");
// 获取值
console.log(input.value);
// 设置值
input.value = "新值";
// 文本域
const textarea = document.querySelector("textarea");
textarea.value = "多行文本";
// 下拉选择
const select = document.querySelector("select");
console.log(select.value);
select.value = "option1";
// 复选框
const checkbox = document.querySelector("input[type='checkbox']");
console.log(checkbox.checked); // true/false
checkbox.checked = true;
// 单选框
const radios = document.querySelectorAll("input[name='gender']");
radios.forEach(radio => {
if (radio.checked) {
console.log(radio.value);
}
});3. 表单提交
javascript
const form = document.querySelector("form");
form.addEventListener("submit", function(event) {
event.preventDefault(); // 阻止默认提交
// 获取表单数据
const formData = new FormData(form);
const data = Object.fromEntries(formData);
console.log(data);
// 手动提交
// form.submit();
});九、常用方法
1. 类名操作
javascript
const element = document.querySelector("div");
element.classList.add("active");
element.classList.remove("active");
element.classList.toggle("active");
element.classList.contains("active");
element.classList.replace("old-class", "new-class");2. 滚动操作
javascript
window.scrollTo(0, 0); // 滚动到顶部
document.querySelector("#section").scrollIntoView({ behavior: "smooth" });
// 获取滚动位置
console.log(window.scrollX);
console.log(window.scrollY);3. 尺寸操作
javascript
const element = document.querySelector("div");
// 元素尺寸
console.log(element.offsetWidth); // 包括 padding、border
console.log(element.offsetHeight);
console.log(element.clientWidth); // 包括 padding
console.log(element.clientHeight);
// 位置
console.log(element.offsetLeft);
console.log(element.offsetTop);总结
DOM 操作是前端开发的核心,熟练掌握各种方法可以高效地操作页面元素和实现交互效果。