十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
DOM TUTORIAL

JavaScript DOM 操作教程

从 DOM 树到事件、动画,把网页从“能看”推进到“能用”。

JavaScript DOM 操作教程:从获取元素到做出动画

JavaScript DOM 操作教程封面图

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 异步请求,做出真正“数据驱动”的页面。

返回教程中心