DOM 常用 API 速查表

一、获取 DOM 元素

这是最基础的一组。

1. getElementById

复制代码
const app = document.getElementById('app')

根据 id 获取元素。


2. getElementsByClassName

复制代码
const items = document.getElementsByClassName('item')

返回:

复制代码
HTMLCollection

注意它通常是实时集合(live collection)。


3. getElementsByTagName

复制代码
const divs = document.getElementsByTagName('div')

获取指定标签。


4. querySelector

复制代码
const el = document.querySelector('.item')

返回第一个匹配元素。


5. querySelectorAll

复制代码
const els = document.querySelectorAll('.item')

返回:

复制代码
NodeList

常用于批量查询。


面试重点

一定要知道:

复制代码
getElementsByClassName
getElementsByTagName
        ↓
HTMLCollection
        ↓
通常是 live

querySelectorAll
        ↓
NodeList
        ↓
通常是 static

二、DOM 树关系

这组非常重要,你刚才写 DFS 就用到了。

假设:

复制代码
<div id="parent">
  <div id="child">
    <span id="grandchild"></span>
  </div>
</div>

parentElement

获取父元素:

复制代码
child.parentElement

结果:

复制代码
parent

children

获取元素子节点:

复制代码
parent.children

结果:

复制代码
HTMLCollection
├── div#child

重点:

children 只包含 Element,不包含文本节点。


childNodes

复制代码
parent.childNodes

它包含:

  • Element

  • Text

  • Comment

比如 HTML:

复制代码
<div>
  hello
  <span></span>
</div>

空格和换行本身也可能形成 Text Node。

所以:

复制代码
children

和:

复制代码
childNodes

一定要区分。


firstElementChild

复制代码
parent.firstElementChild

第一个元素子节点。


lastElementChild

复制代码
parent.lastElementChild

最后一个元素子节点。


nextElementSibling

复制代码
child.nextElementSibling

下一个兄弟元素。


previousElementSibling

复制代码
child.previousElementSibling

上一个兄弟元素。


三、创建、插入、删除 DOM

这组实际开发非常常用。

创建

复制代码
const div = document.createElement('div')

设置内容

复制代码
div.textContent = 'hello'

或者:

复制代码
div.innerHTML = '<span>hello</span>'

两者区别非常重要:

复制代码
textContent

把内容当普通文本。

复制代码
innerHTML

把字符串解析成 HTML。


添加子节点

复制代码
parent.appendChild(child)

append

复制代码
parent.append(child)

也可以:

复制代码
parent.append('hello')

prepend

复制代码
parent.prepend(child)

插到第一个。


before

复制代码
element.before(newElement)

after

复制代码
element.after(newElement)

删除

复制代码
element.remove()

替换

复制代码
parent.replaceChild(newChild, oldChild)

现代 API:

复制代码
oldChild.replaceWith(newChild)

四、属性 Attribute

这个很重要,因为:

复制代码
<div id="app" data-id="123"></div>

这里的:

复制代码
id
data-id

属于 HTML Attribute。


getAttribute

复制代码
el.getAttribute('data-id')

setAttribute

复制代码
el.setAttribute('data-id', '456')

hasAttribute

复制代码
el.hasAttribute('data-id')

removeAttribute

复制代码
el.removeAttribute('data-id')

五、class 操作

这个在 Vue/React 原生 DOM 操作里都很常见。

classList

复制代码
el.classList

它是:

复制代码
DOMTokenList

添加

复制代码
el.classList.add('active')

删除

复制代码
el.classList.remove('active')

判断

复制代码
el.classList.contains('active')

切换

复制代码
el.classList.toggle('active')

例如:

复制代码
el.classList.toggle('active')

有:

复制代码
active → 删除

没有:

复制代码
没有 active → 添加

六、style

直接操作内联样式:

复制代码
el.style.width = '100px'
el.style.height = '200px'
el.style.display = 'none'

也可以:

复制代码
el.style.cssText = `
  width: 100px;
  height: 200px;
`

不过实际开发一般不建议大量操作 cssText。


七、获取真实尺寸

这个是学习虚拟列表、ResizeObserver、性能优化特别应该掌握的一组。


getBoundingClientRect()

复制代码
const rect = el.getBoundingClientRect()

得到:

复制代码
{
  x,
  y,
  width,
  height,
  top,
  right,
  bottom,
  left
}

例如:

复制代码
rect.height

就是元素当前渲染出来的高度。


offsetWidth

复制代码
el.offsetWidth

通常表示:

复制代码
content
+ padding
+ border

offsetHeight

复制代码
el.offsetHeight

同理。


clientWidth

复制代码
el.clientWidth

通常:

复制代码
content + padding

不包含 border。


clientHeight

复制代码
el.clientHeight

scrollWidth

复制代码
el.scrollWidth

元素内容实际需要的宽度。

例如:

复制代码
┌──────────────┐
│ 可视区域     │
│              │
└──────────────┘
←──────────────→
     500px

但是里面内容有:

复制代码
1000px

那么:

复制代码
el.clientWidth  // 500
el.scrollWidth  // 1000

scrollHeight这个你在聊天虚拟列表里已经用到了:

复制代码
el.scrollHeight

表示内容的完整滚动高度。


scrollTop

复制代码
el.scrollTop

当前滚动了多少。


scrollLeft

复制代码
el.scrollLeft

八、滚动相关 API

scrollTo

复制代码
el.scrollTo({
  top: 1000,
  behavior: 'smooth'
})

scrollBy

复制代码
el.scrollBy({
  top: 100
})

表示:

在当前位置基础上再滚 100px。


scrollIntoView

复制代码
el.scrollIntoView()

让元素进入视口。

也可以:

复制代码
el.scrollIntoView({
  behavior: 'smooth',
  block: 'center'
})

九、事件

这个也是 DOM 核心知识。

添加事件

复制代码
el.addEventListener('click', handler)

删除事件

复制代码
el.removeEventListener('click', handler)

注意必须是同一个函数引用:

复制代码
function handler() {}

el.addEventListener('click', handler)

el.removeEventListener('click', handler)

不能:

复制代码
el.removeEventListener('click', () => {})

因为不是同一个函数。


十、事件对象

复制代码
el.addEventListener('click', (event) => {
  console.log(event)
})

常见:

复制代码
event.target
event.currentTarget
event.preventDefault()
event.stopPropagation()

target

真正触发事件的元素。

currentTarget

当前绑定事件监听器的元素。

这是面试高频题。


十一、事件传播

DOM 事件:

复制代码
捕获阶段
   ↓
target
   ↓
冒泡阶段

例如:

复制代码
<div id="parent">
  <button id="child">点击</button>
</div>

:

复制代码
parent.addEventListener('click', () => {
  console.log('parent')
})

child.addEventListener('click', () => {
  console.log('child')
})

点击 button:

复制代码
child
parent

可以指定捕获:

复制代码
parent.addEventListener(
  'click',
  handler,
  true
)

或者:

复制代码
parent.addEventListener('click', handler, {
  capture: true
})

十二、节点操作

这个是面试手写 DOM 题经常出现的。

cloneNode

复制代码
const copy = element.cloneNode(true)

true:

连后代一起复制。

复制代码
cloneNode(false)

只复制自己。


contains

复制代码
parent.contains(child)

判断:

child 是否是 parent 的后代。


matches

复制代码
element.matches('.foo')

判断当前元素是否匹配 CSS selector。


closest

复制代码
element.closest('.container')

从当前元素开始向上寻找最近的匹配祖先。

这个实际开发非常常用。

例如事件委托:

复制代码
container.addEventListener('click', e => {
  const button = e.target.closest('button')

  if (!button) return

  // ...
})

十三、MutationObserver

ResizeObserver

关注:

复制代码
尺寸变化

const observer = new ResizeObserver(entries => {
  console.log(entries)
})

observer.observe(element)

MutationObserver

关注 DOM 结构/属性变化:

复制代码
const observer = new MutationObserver(mutations => {
  console.log(mutations)
})

observer.observe(element, {
  childList: true,
  attributes: true,
  subtree: true
})

简单记:

复制代码
ResizeObserver
→ 尺寸变了

MutationObserver
→ DOM/属性变了

IntersectionObserver
→ 元素和视口的交叉状态变了

十四、IntersectionObserver

懒加载、无限滚动非常常见。

复制代码
const observer = new IntersectionObserver(entries => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      console.log('进入视口')
    }
  })
})

observer.observe(element)

例如:

复制代码
列表
 ↓
 ↓
 ↓
[加载更多 sentinel]

当 sentinel 进入视口:

复制代码
IntersectionObserver
       ↓
加载下一页

十五、你现在最应该掌握的 DOM API

如果是为了前端面试,我建议按照这个优先级:

第一梯队:一定熟练

复制代码
getElementById
querySelector
querySelectorAll

children
childNodes
parentElement
firstElementChild
lastElementChild
nextElementSibling
previousElementSibling

createElement
appendChild
append
prepend
remove
replaceWith

getAttribute
setAttribute
removeAttribute

classList
textContent
innerHTML

addEventListener
removeEventListener

target
currentTarget
preventDefault
stopPropagation

第二梯队:你现在虚拟列表特别需要

复制代码
getBoundingClientRect
offsetWidth
offsetHeight
clientWidth
clientHeight
scrollWidth
scrollHeight
scrollTop
scrollLeft

scrollTo
scrollBy
scrollIntoView

第三梯队:高级前端非常常用

复制代码
ResizeObserver
MutationObserver
IntersectionObserver

closest
matches
contains
cloneNode

适合现在阶段的学习顺序

建议按这个顺序:

复制代码
① DOM 树
   ↓
children / childNodes / parentElement
   ↓
nextElementSibling / firstElementChild

② DOM 增删改
   ↓
createElement / append / remove
   ↓
innerHTML / textContent

③ CSS / 属性
   ↓
classList / style
   ↓
getAttribute / dataset

④ 尺寸与滚动
   ↓
clientHeight
offsetHeight
scrollHeight
getBoundingClientRect
scrollTop

⑤ 事件
   ↓
addEventListener
   ↓
target / currentTarget
   ↓
捕获 / 冒泡 / 事件委托

⑥ Observer
   ↓
ResizeObserver
MutationObserver
IntersectionObserver

⑦ 最后再结合
   ↓
虚拟列表
无限滚动
懒加载
聊天流式渲染

尤其是 children / childNodes、clientHeight / offsetHeight / scrollHeight、target / currentTarget、三种 Observer。

相关推荐
YYYing.3 分钟前
【设计模式系列 (五) 】原型模式
开发语言·后端·设计模式·原型模式·c/c++
重生之小比特6 分钟前
【C++进阶】哈希表实现
开发语言·c++·哈希
m0_3807438717 分钟前
VisualStudio中OpenCV的创建与配置使用小结
开发语言·c++
凉茶钱30 分钟前
【C++】动态内存管理完整解析:从内存划分到 new delete 底层原理
c语言·开发语言·c++·内存管理·动态内存
小七在进步32 分钟前
类和对象(五)
java·开发语言·算法
Rebecca_aLi35 分钟前
码匠教育:零基础学 Python,标识符到循环全套基础语法解析
开发语言·python·正则表达式
就叫年华吧丶41 分钟前
长文档点目录定位总是不准?一个 content-visibility + 平滑滚动引发的连环坑(Vue3 实战)
前端·javascript·算法·vue
IvanCodes42 分钟前
Python 正则表达式(十四):文本匹配、查找与替换
开发语言·python·正则表达式
夜雪一千42 分钟前
Python URL编码踩坑:单层编码、双重编码实战解析
开发语言·python
孙启超1 小时前
【AI开发之Rust】第 21 课:双端集成与出包 —— Android(.so→AAR)与 iOS(xcframework)
开发语言·后端·rust