DOM 是浏览器把 HTML 解析后生成的对象树,JS 通过 DOM API 读写这棵树,就能动态改变页面内容与样式。本篇是《JavaScript 入门教程》的进阶篇,深入讲 DOM 的五个核心操作。
一、DOM 树
浏览器加载 HTML 后,会把它解析成一棵由节点(Node)组成的树状结构,根节点是 document。每个标签是一个元素节点(Element),标签里的文字是文本节点(Text),属性是属性节点(Attribute)。理解这棵树,才能精准定位到要操作的元素。
// document 是整棵树的根
document.documentElement; // <html>
document.body; // <body>
// 节点关系
el.parentNode; // 父节点
el.children; // 子元素集合
el.nextElementSibling; // 下一个兄弟元素
二、获取元素
操作 DOM 的第一步是“选中它”。现代 JS 推荐用 querySelector 系列,写法与 CSS 选择器一致,灵活且好读。
// 选单个
const btn = document.querySelector("#submitBtn");
const firstCard = document.querySelector(".card");
// 选全部(返回 NodeList,可用 forEach)
const items = document.querySelectorAll(".menu-item");
items.forEach(item => {
console.log(item.textContent);
});
// 按传统方式(仍可用,但不够灵活)
document.getElementById("logo");
document.getElementsByClassName("tag");
document.getElementsByTagName("p");
拓冰提示
querySelectorAll 返回的是静态 NodeList,可以 forEach;而 getElementsByClassName 返回的是动态 HTMLCollection,不能直接 forEach,新手常踩这个坑。优先用前者。
三、修改内容
拿到元素后,最常见的操作就是改它的内容、属性、样式。下面几个 API 覆盖 90% 日常需求。
// 改文本
title.textContent = "新标题";
// 改 HTML(注意 XSS 风险)
box.innerHTML = "<p>带样式的<strong>内容</strong></p>";
// 改属性
img.src = "images/cover.jpg";
link.setAttribute("target", "_blank");
// 改类
btn.classList.add("active");
btn.classList.remove("active");
btn.classList.toggle("active"); // 有则删,无则加
// 改样式(行内样式)
box.style.color = "#2D4A3E";
box.style.opacity = "0.8";
避坑提醒
动态拼接
innerHTML 是 XSS 注入的高发区。如果内容来自用户输入,务必先转义,或用 textContent。改样式也尽量通过切换 class 而非直接写 style,便于维护。
四、事件监听
事件是用户与页面交互的信号。addEventListener 是监听事件的现代写法,可以给同一元素绑定多个回调,也能用 removeEventListener 解绑。
const tab = document.querySelector(".tab");
// 绑定
function handleClick(e) {
console.log("被点击了", e.target);
e.preventDefault(); // 阻止默认行为
}
tab.addEventListener("click", handleClick);
// 解绑(必须传同一函数引用)
tab.removeEventListener("click", handleClick);
// 事件委托:把子元素的事件统一交给父元素
document.querySelector(".list").addEventListener("click", e => {
if (e.target.matches(".item")) {
console.log("点了", e.target.textContent);
}
});
“事件委托”是 DOM 编程的精华技巧:动态生成的子元素也能响应事件,无需逐个绑定,性能也好。
五、动画
动画有两种思路:CSS 动画(transition / keyframes)适合简单过渡,性能好;JS 动画适合需要复杂逻辑的场景。能 CSS 就别 JS,把主线程留给交互。
// 思路一:JS 切换 class,动画交给 CSS
box.classList.add("show");
/* CSS:.box.show { opacity:1; transform:none; transition:all .3s; } */
// 思路二:requestAnimationFrame 做逐帧动画
function fadeIn(el, duration = 400) {
el.style.opacity = 0;
el.style.transition = `opacity ${duration}ms ease`;
requestAnimationFrame(() => {
el.style.opacity = 1;
});
}
fadeIn(document.querySelector(".banner"));
避坑提醒
永远别用
setInterval 做动画——它不与屏幕刷新同步,会掉帧卡顿。要逐帧动画就用 requestAnimationFrame,浏览器会自动优化。
掌握这五块,轮播、选项卡、抽屉菜单、表单校验等常见交互你已经能独立完成。后续可继续学习 fetch 异步请求,做出真正“数据驱动”的页面。