2.1 DOM 概念与节点树
DOM = Document Object Model(文档对象模型)
大白话:浏览器把 HTML 页面变成了一棵"树"——每个 HTML 标签、每段文字、每个属性都是树上的一个"节点"。JavaScript 通过这棵树来找到、读取、修改页面上的任何内容。
2.1.1 DOM 节点树层级结构
想象一下,整个 HTML 文档被浏览器变成了这样一棵"倒着长的树":
- 文档节点(document):整棵树的根,代表整个页面
- 根节点(
<html>):树的"树干",下面分两个大分支 - 元素节点:每个 HTML 标签(
<head>、<body>、<h1>、<p>等) - 文本节点:标签里面包着的文字
- 属性节点:标签上的属性(如
class="red"、id="main") - 注释节点:
<!-- 注释内容 -->
2.1.2 四大节点详解
| 节点类型 | 大白话 | 举例 |
|---|---|---|
| 元素节点 | HTML 标签本身 | <h1>、<p>、<div> |
| 文本节点 | 标签里的文字 | "你好世界"、"这是一个段落" |
| 属性节点 | 标签上的属性 | class="red"、id="main"、href="#" |
| 注释节点 | HTML 注释 | <!-- 这里是注释 --> |
2.1.3 head 和 body 常用标签节点
<head> 分支下的常用节点:
<body> 分支下的常用节点:
2.2 获取元素节点
想操作页面元素,第一步是找到它。JavaScript 提供了几种"找人"的方法。
最常用的三种方法:
| 方法 | 用法 | 返回 |
|---|---|---|
getElementById('id名') |
通过 id 找元素 | 一个元素 |
getElementsByTagName('标签名') |
通过标签名找 | 多个元素(类数组) |
getElementsByClassName('类名') |
通过类名找 | 多个元素(类数组) |
这是一个段落,有 id 属性。
这是第一个段落(class="text")
这是第二个段落(class="text")
- 项目1
- 项目2
- 项目3
getElementById 是单数(Element),只返回一个;getElementsByTagName 是复数(Elements),返回多个。方法名必须写对,大小写敏感。
getElementsByTagName 或 getElementsByClassName 获取到的是动态集合,如果页面元素变化,这个集合也会自动更新。
2.3 修改元素内容与属性
找到元素之后,就可以改它的内容或属性了。
2.3.1 修改内容
innerHTML 获取或设置元素里的 HTML 内容(可以包含标签)
innerText 获取或设置元素里的纯文本(标签会被忽略)
textContent 类似 innerText,但保留所有文本
这是原始内容
| 属性 | 能识别 HTML 标签? | 场景 |
|---|---|---|
innerHTML |
✅ 能 | 需要插入带格式的内容 |
innerText |
❌ 不能 | 只想改文字,防止注入 |
innerHTML 如果用户输入的内容直接赋值进去,有安全风险。如果用 innerText,所有内容都会被当作纯文本,不会解析标签,更安全。
2.3.2 修改属性
| 属性 | 示例 | 说明 |
|---|---|---|
href |
link.href = '...' |
修改链接地址 |
src |
img.src = '...' |
修改图片路径 |
alt |
img.alt = '...' |
修改替代文字 |
title |
img.title = '...' |
修改悬停提示 |
id |
div.id = 'newId' |
修改 id |
className |
div.className = 'newClass' |
修改 class(注意不是 class) |
class 属性时,要用 className 而不是 class。因为 class 是 JavaScript 的保留字,所以 DOM 中用 className 代替。
2.4 样式操作
修改元素的 CSS 样式有三种方式。
方式一:直接修改 style 属性
这段文字会变色 🎨
| CSS 属性 | JavaScript 写法(驼峰命名) |
|---|---|
background-color |
backgroundColor |
font-size |
fontSize |
margin-top |
marginTop |
border-radius |
borderRadius |
- 去掉,后面首字母大写。background-color → backgroundColor。
方式二:通过 className 切换样式
元素.className = '类名' 可以整体替换元素的 class 属性。
方式三:通过 classList 添加/移除类(推荐)
classList 提供了更灵活的类操作:
元素.classList.add('类名') // 添加一个类
元素.classList.remove('类名') // 移除一个类
元素.classList.toggle('类名') // 切换(有就删,没有就加)
| 方式 | 代码 | 适用场景 |
|---|---|---|
style 属性 |
div.style.color = 'red' |
改变单个样式属性 |
className |
div.className = 'highlight' |
整体切换预定义的样式类 |
classList |
div.classList.add('active') |
推荐,灵活不覆盖原有类 |
style 设置 CSS 属性时,属性名用驼峰命名,不能带 -。backgroundColor 不是 background-color。
className = 'highlight' 会覆盖元素原来的所有 class。如果原来有 class="normal big",赋值后变成 class="highlight"。要用 classList.add() 来追加。
2.5 节点增删改
除了修改已有元素,JavaScript 还可以创建新元素、插入页面、删除元素。
2.5.1 创建和插入节点
document.createElement('标签名') — 创建新元素
新元素.innerText = '...' — 添加内容
父元素.appendChild(新元素) — 放到最后
父元素.insertBefore(新元素, 参照元素) — 放到某个元素前面
2.5.2 删除节点
父元素.removeChild(子元素) — 删除子元素
元素.remove() — 直接删除自己(推荐)
2.5.3 替换节点
父元素.replaceChild(新元素, 旧元素)
- 项目 A
- 项目 B
- 项目 C
| 操作 | 方法 | 说明 |
|---|---|---|
| 创建元素 | document.createElement('标签') |
创建新元素 |
| 添加内容 | 元素.innerText = '...' |
设置文字 |
| 插入末尾 | 父元素.appendChild(子元素) |
加到最后一个 |
| 插入前面 | 父元素.insertBefore(新, 参照) |
加在某个元素前 |
| 删除子元素 | 父元素.removeChild(子元素) |
删除指定的子元素 |
| 删除自己 | 元素.remove() |
直接删除自己 |
| 替换子元素 | 父元素.replaceChild(新, 旧) |
用新元素替换旧元素 |
createElement 只是创建了"虚拟"的元素,还没放到页面上。必须用 appendChild、insertBefore 等方法插入到 DOM 树才能看到。
removeChild 需要先拿到父元素,再指定要删哪个子元素。而 元素.remove() 更直接,不需要知道父元素是谁。
2.6 基础事件
事件就是用户的操作(点击按钮、鼠标滑过、页面加载……),JavaScript 可以"监听"这些事件,然后做出响应。
2.6.1 点击事件(onclick)
最常用的事件——用户点击某个元素时触发。
方式一:在 HTML 中绑定(行内) <button onclick="alert('点')">点我</button>
方式二:在 JS 中绑定(推荐) btn.onclick = function() { ... };
2.6.2 页面载入事件(onload)
window.onload = function() { ... }; — 页面完全加载后执行。
如果你把 <script> 放在 <head> 里,脚本执行时 <body> 还没解析完,getElementById 就找不到元素。window.onload 保证等整个页面准备好了再执行。
2.6.3 其他常见事件
| 事件 | 触发时机 | 示例 |
|---|---|---|
onclick |
点击元素 | btn.onclick = fn |
ondblclick |
双击元素 | btn.ondblclick = fn |
onmouseover |
鼠标移到元素上 | div.onmouseover = fn |
onmouseout |
鼠标离开元素 | div.onmouseout = fn |
onchange |
表单内容改变 | input.onchange = fn |
onfocus |
元素获得焦点 | input.onfocus = fn |
onblur |
元素失去焦点 | input.onblur = fn |
btn.onclick = myFunc ✅(把函数本身赋值),btn.onclick = myFunc() ❌(这样是直接把函数执行结果赋值,不是绑定事件)。
window.onload 只能绑定一个函数。如果再写一次 window.onload = function(){},会覆盖前一个。如果需要在页面加载后执行多个操作,可以把所有操作放在一个 onload 函数里。
2.7 简易实战
综合运用前面学到的知识,完成几个能直接运行的交互小项目。
📋 实战一:待办事项列表
点击按钮添加新的待办事项,点击事项可以删除它。
🔢 实战二:点击计数器
每点一次按钮,数字加 1。点击归零可以重置。
🖼️ 实战三:简易图片轮播(手动切换)
点击"上一张"或"下一张"切换图片。
| 项目 | 用到的知识点 |
|---|---|
| 待办事项 | 获取元素、创建元素、事件绑定、增删节点 |
| 点击计数器 | 变量、事件绑定、修改元素内容 |
| 图片轮播 | 数组、事件绑定、修改属性(src)、条件判断 |