Skip to content

DOM

选择元素、处理事件,并用文档对象模型更新页面。

你将学到

  • 什么是 DOM,浏览器如何从 HTML 构建它
  • 用 querySelector 和 getElementById 选择元素
  • 用 textContent 和 innerHTML 修改内容
  • 用 addEventListener 处理事件
  • 创建并追加新元素

概念讲解

什么是 DOM?

文档对象模型(DOM)是 HTML 的实时树状表示,JavaScript 可以读取和修改它。浏览器加载页面时,会解析 HTML 并构建这棵树。每个 HTML 元素都成为一个节点,你可以通过 document 访问。

document
  └── html
      ├── head
      │   └── title
      └── body
          ├── h1
          ├── p
          └── button

选择元素

// 按 ID——返回单个元素或 null
const title = document.getElementById("main-title");

// 按 CSS 选择器——仅第一个匹配
const button = document.querySelector(".btn-primary");

// 所有匹配——返回 NodeList
const items = document.querySelectorAll("li");

querySelectorquerySelectorAll 接受任何 CSS 选择器,最灵活,是现代默认选择。

修改内容

const heading = document.querySelector("h1");
heading.textContent = "Updated Title"; // 安全——设置纯文本
heading.innerHTML = "<span>HTML</span>"; // 解析 HTML——有 XSS 风险!

只需纯文本时优先用 textContentinnerHTML 会把字符串解析为 HTML,如果内容含用户输入,可能引入跨站脚本(XSS)漏洞。

处理事件

const button = document.querySelector("button");
button.addEventListener("click", (event) => {
  console.log("Clicked!", event.target);
});

常见事件:clickinputchangesubmitkeydownmouseover。回调会收到一个事件对象,包含发生了什么的细节。

创建并追加元素

const list = document.querySelector("ul");
const newItem = document.createElement("li");
newItem.textContent = "A new item";
newItem.classList.add("highlight");
list.appendChild(newItem);

classList 操作样式

const card = document.querySelector(".card");
card.classList.add("active");
card.classList.remove("hidden");
card.classList.toggle("selected"); // 有则移除,无则添加

关于框架的说明

现代应用常用 React、Vue 或 Svelte,而非直接操作 DOM。但理解 DOM 仍然必不可少——框架是对它的抽象,浏览器扩展、原生脚本以及理解框架底层原理都需要它。

示例代码

              // 选择按钮和输出区域
const button = document.querySelector("#counter-btn");
const display = document.querySelector("#count-display");

let count = 0;

// 更新显示
function updateDisplay() {
  display.textContent = `Count: ${count}`;
  // 根据计数切换 CSS 类
  display.classList.toggle("even", count % 2 === 0);
}

// 处理点击
button.addEventListener("click", () => {
  count++;
  updateDisplay();

  // 动态创建日志条目
  if (count <= 5) {
    const log = document.createElement("p");
    log.textContent = `Clicked ${count} time(s)`;
    document.querySelector("#log").appendChild(log);
  }
});

// 处理键盘快捷键
document.addEventListener("keydown", (e) => {
  if (e.key === "r") {
    count = 0;
    updateDisplay();
  }
});

updateDisplay(); // 初始化
            

一个可工作的计数器:选择元素、安全更新 textContent、切换 CSS 类、创建并追加日志、监听键盘快捷键。把这段代码粘贴到有对应元素的页面即可运行。

动手试一试

常见错误

错误写法

用 innerHTML 处理用户输入,造成 XSS 漏洞

正确做法

永远不要把不可信数据放进 innerHTML。纯文本用 textContent,或先对 HTML 消毒。React 等框架默认会转义值,正是这个原因。

错误写法

在元素存在之前调用 querySelector

正确做法

把脚本放在 body 末尾,或用 DOMContentLoaded 包裹:document.addEventListener('DOMContentLoaded', () => { ... })。否则 querySelector 返回 null。

相关代码片段

相关速查表

练习 DOM

2 个练习

练习 DOM

查阅不认识的术语

新手友好的术语表用大白话解释编程术语——变量、函数、DOM、Promise 等等。

查看术语表

动手做项目

通过引导式项目应用所学,含起始代码与解决方案。

查看项目

解读错误信息

用大白话解释常见错误——什么意思、为什么发生、如何修复。

查看错误