【Web APIs-Day1】DOM操作基础
📺 对应视频:P78-P93 | 🎯 核心目标:理解DOM树、掌握获取元素的多种方式、修改内容/属性/样式、使用定时器
一、Web APIs 概述
1.1 API 是什么?
API(Application Programming Interface)是接口,是别人封装好的功能,我们直接调用。
Web APIs 是浏览器提供的接口,分两大类:
- DOM(Document Object Model):操作 HTML 文档
- BOM(Browser Object Model):操作浏览器窗口
1.2 DOM 是什么?
DOM 将 HTML 文档映射为一个树形结构,每个 HTML 标签都是树上的一个节点(Node) 。
document(文档节点)
└── html(元素节点)
├── head
│ └── title(#text "标题")
└── body
├── div#app
│ ├── h1(#text "Hello")
│ └── p(#text "World")
└── script
节点类型:
- 元素节点(Element) :HTML 标签,如
<div> - 文本节点(Text) :标签内的文本内容
- 属性节点(Attr) :标签的属性,如
class="box" - 注释节点(Comment) :HTML 注释
二、获取 DOM 元素
2.1 新式 API(推荐)
// querySelector:获取匹配CSS选择器的第一个元素
document.querySelector('.box') // 类名
document.querySelector('#title') // id
document.querySelector('p') // 标签
document.querySelector('.list li:first-child') // 复杂选择器
// querySelectorAll:获取所有匹配的元素(NodeList)
document.querySelectorAll('li') // 所有 li
document.querySelectorAll('.item') // 所有 class=item 的元素
// ⚠️ querySelectorAll 返回 NodeList(类数组),需要遍历
const items = document.querySelectorAll('.item')
items.forEach(item => {
console.log(item.textContent)
})
2.2 旧式 API(了解)
document.getElementById('myId') // 通过 id 获取
document.getElementsByClassName('myClass') // 通过类名获取(HTMLCollection)
document.getElementsByTagName('div') // 通过标签名获取
// 特殊元素
document.body // body 元素
document.head // head 元素
document.title // title 文本
document.documentElement // html 元素
💡 推荐:日常开发使用
querySelector和querySelectorAll,语法与 CSS 选择器一致,学习成本低。
三、操作元素内容
3.1 textContent vs innerHTML
let div = document.querySelector('div')
// textContent:纯文本内容(安全,推荐用于纯文本)
div.textContent // 获取(包含所有后代文本)
div.textContent = '<b>粗体</b>' // 设置(标签会被当作文本显示,不解析)
// innerHTML:HTML 内容(可以解析标签)
div.innerHTML // 获取(包含HTML标签)
div.innerHTML = '<b>粗体</b>' // 设置(会解析并渲染 HTML)
// ⚠️ 安全警告:innerHTML 存在 XSS 风险,绝对不要将用户输入直接放入 innerHTML
// 错误示范:
div.innerHTML = userInput // 如果 userInput = '<script>恶意代码</script>'
四、操作元素属性
4.1 HTML 标准属性
let img = document.querySelector('img')
let input = document.querySelector('input')
let a = document.querySelector('a')
// 读写标准属性(直接通过属性名)
img.src = 'https://example.com/pic.jpg'
img.alt = '图片描述'
a.href = 'https://juejin.cn'
input.value = '输入框的值'
input.type = 'password'
input.checked = true // 复选框选中
input.disabled = false // 是否禁用
4.2 自定义属性(data-* 属性)
<!-- HTML -->
<div id="box" data-id="123" data-user-name="张三"></div>
let box = document.querySelector('#box')
// 读取 data-* 属性
box.dataset.id // '123'
box.dataset.userName // '张三'(驼峰命名,去掉 data-,连字符转驼峰)
// 设置 data-* 属性
box.dataset.status = 'active' // 自动添加 data-status 属性
4.3 getAttribute / setAttribute / removeAttribute
// 处理非标准属性 or 需要精确控制时使用
let el = document.querySelector('.box')
el.getAttribute('class') // 'box'
el.getAttribute('data-id') // '123'(也可以读 data-*)
el.setAttribute('data-id', '456')
el.removeAttribute('data-id')
el.hasAttribute('data-id') // false(删除后)
五、操作样式
5.1 行内样式(style 属性)
let box = document.querySelector('.box')
// 设置单个样式(CSS属性名转驼峰命名)
box.style.width = '200px'
box.style.backgroundColor = 'red' // background-color → backgroundColor
box.style.fontSize = '18px'
box.style.display = 'none' // 隐藏元素
// 读取行内样式
console.log(box.style.width) // '200px'(只能读行内样式)
console.log(box.style.color) // ''(如果样式在CSS文件里,读不到)
5.2 className 操作
// className(字符串操作,替换所有类名)
box.className = 'active' // 替换(覆盖原来的类名,危险!)
box.className += ' active' // 追加(容易加空格bug)
5.3 classList 操作(推荐)
let box = document.querySelector('.box')
// classList 方法(精准操作类名)
box.classList.add('active') // 添加类名
box.classList.remove('active') // 移除类名
box.classList.toggle('active') // 有就删,没有就加(切换状态)
box.classList.contains('active') // 是否包含某类名(返回布尔)
box.classList.replace('old', 'new') // 替换类名
// 实际应用:点击切换 active 状态
btn.addEventListener('click', () => {
box.classList.toggle('active')
})
5.4 getComputedStyle(读取计算后样式)
// 读取实际生效的样式(包括CSS文件中的)
let style = getComputedStyle(box)
console.log(style.width) // '200px'(计算后的值)
console.log(style.backgroundColor) // 'rgb(255, 0, 0)'
六、定时器
6.1 setTimeout(延迟执行)
// 语法:setTimeout(回调函数, 延迟毫秒数)
let timer = setTimeout(() => {
console.log('2秒后执行')
}, 2000)
// 取消定时器
clearTimeout(timer)
// 实际应用:自动关闭弹窗
function showAlert(msg, delay = 3000) {
const box = document.createElement('div')
box.textContent = msg
document.body.appendChild(box)
setTimeout(() => box.remove(), delay)
}
6.2 setInterval(重复执行)
// 语法:setInterval(回调函数, 间隔毫秒数)
let count = 0
let interval = setInterval(() => {
count++
console.log(`第${count}次`)
if (count >= 5) clearInterval(interval) // 执行5次后停止
}, 1000)
// 取消定时器
clearInterval(interval)
实际应用:倒计时
function countdown(seconds) {
let remaining = seconds
const display = document.querySelector('#countdown')
display.textContent = remaining
const timer = setInterval(() => {
remaining--
display.textContent = remaining
if (remaining <= 0) {
clearInterval(timer)
display.textContent = '时间到!'
}
}, 1000)
}
countdown(60) // 60秒倒计时
七、综合案例
案例1:轮播图自动播放
const images = ['img1.jpg', 'img2.jpg', 'img3.jpg']
const img = document.querySelector('.banner img')
let current = 0
setInterval(() => {
current = (current + 1) % images.length
img.src = images[current]
}, 3000)
案例2:随机更换背景色
function randomColor() {
const r = Math.floor(Math.random() * 256)
const g = Math.floor(Math.random() * 256)
const b = Math.floor(Math.random() * 256)
return `rgb(${r}, ${g}, ${b})`
}
setInterval(() => {
document.body.style.backgroundColor = randomColor()
}, 1000)
八、知识图谱
DOM 操作基础
├── DOM 树
│ └── 节点类型:元素、文本、属性、注释
├── 获取元素
│ ├── querySelector(单个)
│ ├── querySelectorAll(多个,NodeList)
│ └── 旧式:getElementById/ByClassName/ByTagName
├── 操作内容
│ ├── textContent(纯文本,安全)
│ └── innerHTML(HTML,注意XSS)
├── 操作属性
│ ├── 标准属性:el.src / el.href 等
│ ├── data-* 属性:el.dataset.xxx
│ └── getAttribute/setAttribute/removeAttribute
├── 操作样式
│ ├── el.style.xxx(行内,驼峰命名)
│ ├── el.classList(add/remove/toggle/contains)
│ └── getComputedStyle(读取计算样式)
└── 定时器
├── setTimeout(延迟,clearTimeout取消)
└── setInterval(重复,clearInterval取消)
九、高频面试题
Q1: textContent 和 innerHTML 的区别?
textContent只处理纯文本,不解析 HTML 标签,更安全;innerHTML会解析和渲染 HTML。当内容来自用户输入时必须用textContent,避免 XSS 攻击。
Q2: querySelector 和 getElementById 有什么区别?
querySelector接受完整的 CSS 选择器,更灵活;getElementById只能通过 id 查找,但性能略好(直接查 id 索引)。现代开发推荐querySelector。
Q3:如何读取 CSS 文件中定义的样式?
element.style.xxx只能读行内样式;要读 CSS 文件中的样式,用getComputedStyle(element).xxx,它返回元素实际计算后的最终样式值。
⬅️ 上一篇:JS基础Day5 - 对象与内置对象 ➡️ 下一篇:Web APIs Day2 - 事件监听与事件对象