Skip to content

DOM 文档对象模型

核心基础 JavaScript DOM

一、向网页添加 JavaScript

1.1 三种方式(类比 CSS 的三种方式)

方式语法推荐度
Inline<body onload="alert('Hello')">❌ 避免
Internal<script>alert("Hello")</script>⚠️ 少量使用
External<script src="index.js"></script>✅ 推荐

1.2 script 标签的位置

关键规则

始终将 <script> 放在 </body> 之前,而非 <head> 中。

html
<body>
  <h1>Hello</h1>
  <!-- 所有内容之后 -->
  <script src="index.js"></script>
</body>

原因:

  1. DOM 依赖:如果脚本试图操作尚未加载的元素,会报 Cannot set property of null 错误
  2. 性能:JS 较耗时,放在底部可让页面内容先渲染,用户感知加载更快

1.3 引号嵌套

当 inline JS 中需要字符串时,外层用双引号,内层 降级为单引号

html
<!-- ✅ 正确 -->
<body onload="alert('Hello')">

<!-- ❌ 错误:引号冲突 -->
<body onload="alert("Hello")">

二、什么是 DOM

2.1 概念

DOM(Document Object Model) 是浏览器将 HTML 文档转换为的 树形对象结构。它使 JavaScript 能够动态地 选择操作 页面元素。

document
  └── html
       ├── head
       │    └── title
       └── body
            ├── h1
            ├── input
            ├── button
            ├── ul
            │    ├── li
            │    │    └── a
            │    ├── li
            │    └── li
            └── script

2.2 为什么需要 DOM

  • 静态页面:HTML + CSS 写好后就固定了
  • 动态交互:用户点击按钮 → 需要实时改变内容/样式
  • DOM 的作用:将每个 HTML 元素变成可被 JS 选择和修改的 对象

2.3 DOM 导航

可以通过属性链式访问 DOM 树节点:

javascript
document.firstElementChild                    // <html>
document.firstElementChild.firstElementChild  // <head>
document.firstElementChild.lastElementChild   // <body>
document.firstElementChild.lastElementChild.firstElementChild  // <body> 的第一个子元素

💡 实际开发中不会用这种方式,但它展示了 DOM 是一个可遍历的 树结构


三、选择元素

3.1 五种选择方法

方法返回类型选择依据示例
getElementsByTagName()数组标签名document.getElementsByTagName("li")
getElementsByClassName()数组类名document.getElementsByClassName("btn")
getElementById()单个元素IDdocument.getElementById("title")
querySelector()单个元素CSS 选择器document.querySelector("#title")
querySelectorAll()数组CSS 选择器document.querySelectorAll(".item")

3.2 getElementsBy 系列

javascript
// 返回数组 → 需要用索引访问
document.getElementsByTagName("li")[2].style.color = "purple";

// 即使只有一个元素,也返回数组
document.getElementsByClassName("btn")[0]; // 第一个 .btn 元素

// 唯一返回单个元素的(因为 ID 唯一)
document.getElementById("title").innerHTML = "Good Bye";

注意复数形式

  • getElementsByTagName — 复数,返回 数组
  • getElementsByClassName — 复数,返回 数组
  • getElementById — 单数,返回 单个元素(ID 唯一)

3.3 querySelector(推荐 ⭐)

querySelector 使用 CSS 选择器 语法,功能最强大:

javascript
// 按标签
document.querySelector("h1");

// 按 ID(加 #)
document.querySelector("#title");

// 按 class(加 .)
document.querySelector(".btn");

// 层级选择器(空格 = 后代)
document.querySelector("li a");       // li 内部的 a

// 组合选择器(无空格 = 同一元素)
document.querySelector("li.item");    // 同时是 li 和 .item 的元素

// 复杂组合
document.querySelector("#list .item"); // #list 内的 .item

querySelector vs querySelectorAll:

javascript
// 只返回第一个匹配元素
document.querySelector(".item");

// 返回所有匹配元素(数组)
document.querySelectorAll(".item");

💡 最佳实践:优先使用 querySelector / querySelectorAll,它们比 getElementsBy 更灵活、更常用。


四、操作样式(Style)

4.1 直接修改 style 属性

javascript
document.querySelector("h1").style.color = "red";
document.querySelector("h1").style.fontSize = "10rem";
document.querySelector("button").style.backgroundColor = "yellow";

CSS → JS 属性名转换规则:

  • 去掉连字符 -
  • 后续单词首字母 大写(驼峰)
  • 值必须是 字符串
CSS 属性JS 属性
font-sizefontSize
background-colorbackgroundColor
border-radiusborderRadius
line-heightlineHeight
javascript
// ✅ 值必须是字符串
element.style.padding = "7%";        // 不是 7%
element.style.lineHeight = "2";      // 不是 2
element.style.visibility = "hidden";

参考文档

完整的 JS Style 属性名列表可参考 DOM Style Object Properties


五、关注点分离(Separation of Concerns)

5.1 原则

技术职责
HTML内容(Content)
CSS样式(Style)
JavaScript行为(Behavior)

直接用 JS 修改 .style 属性 违反了 关注点分离——样式逻辑混入了行为代码。

5.2 更好的方式:classList

CSS 中定义样式类,用 JS 切换类名

css
/* styles.css */
.huge {
  font-size: 10rem;
  color: red;
  font-weight: bold;
}

.invisible {
  visibility: hidden;
}
javascript
// 添加类
document.querySelector("h1").classList.add("huge");

// 移除类
document.querySelector("button").classList.remove("invisible");

// 切换类(有则移除,无则添加)
document.querySelector("button").classList.toggle("invisible");

classList 的三个方法:

方法功能示例
.add("class")添加类el.classList.add("active")
.remove("class")移除类el.classList.remove("active")
.toggle("class")切换类el.classList.toggle("active")

最佳实践

样式定义在 CSS 中,JS 只负责 添加/移除类名。这样:

  • 样式问题 → 查 CSS
  • 行为问题 → 查 JS
  • 调试效率大幅提升

六、操作文本(Text / HTML)

6.1 innerHTML vs textContent

javascript
// 假设 HTML: <h1><strong>Hello</strong></h1>

document.querySelector("h1").innerHTML;
// "<strong>Hello</strong>"  ← 包含 HTML 标签

document.querySelector("h1").textContent;
// "Hello"                   ← 纯文本,无标签

区别:

属性返回内容可设置 HTML?
innerHTML标签内的 完整 HTML✅ 可以
textContent标签内的 纯文本❌ 不行
javascript
// 可以通过 innerHTML 注入 HTML
document.querySelector("h1").innerHTML = "<em>Good Bye</em>";
// 结果:h1 中显示斜体的 "Good Bye"

// textContent 会原样显示
document.querySelector("h1").textContent = "<em>Good Bye</em>";
// 结果:h1 中显示文本 "<em>Good Bye</em>"

七、操作属性(Attributes)

7.1 查看、获取、设置

javascript
var link = document.querySelector("a");

// 查看所有属性
link.attributes;           // NamedNodeMap {0: href, ...}

// 获取某个属性的值
link.getAttribute("href"); // "https://www.google.com"

// 设置属性值
link.setAttribute("href", "https://www.bing.com");

属性 = HTML 标签内除标签名外的所有键值对:

html
<a href="..." class="link" id="main-link">
<!--  ^^^^      ^^^^^       ^^  这些都是属性 -->

八、对象的属性与方法

DOM 中的每个元素都是一个 对象,拥有 属性(Properties)方法(Methods)

8.1 类比:汽车对象

javascript
// 属性 — 描述对象的特征
car.color;           // "red"     (getter)
car.numberOfDoors = 0; // 设置为 0  (setter)

// 方法 — 对象能做的事(本质是函数)
car.drive();
car.brake();
car.park();

8.2 DOM 对象示例

javascript
var btn = document.querySelector("button");

// 属性(无括号)
btn.innerHTML;         // 按钮内的 HTML
btn.style.color;       // 文字颜色
btn.firstChild;        // 第一个子节点

// 方法(有括号)
btn.click();           // 模拟点击
btn.appendChild(el);   // 添加子元素
btn.setAttribute("class", "new"); // 修改属性

属性 vs 方法的识别

  • 属性:用 . 访问,无括号btn.innerHTML
  • 方法:用 . 调用,有括号btn.click()

方法本质上就是 关联到对象的函数


← 返回 Web 开发研究