DOM 节点操作
DOM 节点的增删改查、移动和复制方法
问题
掌握 DOM 节点的常用操作:创建、查询、添加、删除、修改、移动和复制。
解答
创建节点
// 创建元素节点
const div = document.createElement('div')
// 创建文本节点
const text = document.createTextNode('Hello')
// 创建文档片段(用于批量操作,避免多次重排)
const fragment = document.createDocumentFragment()
查询节点
// 通过 ID 查询(返回单个元素)
const el = document.getElementById('app')
// 通过类名查询(返回 HTMLCollection)
const items = document.getElementsByClassName('item')
// 通过标签名查询(返回 HTMLCollection)
const divs = document.getElementsByTagName('div')
// CSS 选择器查询(返回第一个匹配元素)
const first = document.querySelector('.item')
// CSS 选择器查询(返回 NodeList)
const all = document.querySelectorAll('.item')
// 获取父节点
const parent = el.parentNode
// 获取子节点
const children = el.children // 只包含元素节点
const childNodes = el.childNodes // 包含所有节点(含文本、注释)
// 获取兄弟节点
const prev = el.previousElementSibling
const next = el.nextElementSibling
添加节点
const parent = document.getElementById('container')
const child = document.createElement('div')
// 末尾添加
parent.appendChild(child)
// 指定位置插入
const reference = parent.children[0]
parent.insertBefore(child, reference) // 在 reference 前插入
// 现代 API(更灵活)
parent.append(child) // 末尾添加,支持多个参数和字符串
parent.prepend(child) // 开头添加
reference.before(child) // 在元素前插入
reference.after(child) // 在元素后插入
删除节点
const el = document.getElementById('target')
// 通过父节点删除
el.parentNode.removeChild(el)
// 直接删除(现代 API)
el.remove()
// 清空子节点
el.innerHTML = ''
// 或者
while (el.firstChild) {
el.removeChild(el.firstChild)
}
修改节点
const el = document.getElementById('target')
// 修改内容
el.textContent = '纯文本内容'
el.innerHTML = '<span>HTML 内容</span>'
// 修改属性
el.setAttribute('data-id', '123')
el.getAttribute('data-id')
el.removeAttribute('data-id')
el.id = 'newId'
el.className = 'new-class'
// 修改样式
el.style.color = 'red'
el.style.cssText = 'color: red; font-size: 14px;'
// 修改类名
el.classList.add('active')
el.classList.remove('active')
el.classList.toggle('active')
el.classList.contains('active')
// 替换节点
const newEl = document.createElement('span')
el.parentNode.replaceChild(newEl, el)
// 或者
el.replaceWith(newEl)
移动节点
// appendChild 和 insertBefore 会自动移动已存在的节点
const el = document.getElementById('item')
const newParent = document.getElementById('newContainer')
// el 会从原位置移动到 newParent 末尾
newParent.appendChild(el)
复制节点
const el = document.getElementById('template')
// 浅复制(不包含子节点)
const shallow = el.cloneNode(false)
// 深复制(包含所有子节点)
const deep = el.cloneNode(true)
// 复制后需要手动添加到 DOM
document.body.appendChild(deep)
完整示例
// 批量创建列表项
function createList(items) {
const ul = document.createElement('ul')
const fragment = document.createDocumentFragment()
items.forEach(item => {
const li = document.createElement('li')
li.textContent = item
li.className = 'x7o55'
fragment.appendChild(li)
})
ul.appendChild(fragment) // 一次性添加,只触发一次重排
return ul
}
// 使用
const list = createList(['苹果', '香蕉', '橙子'])
document.body.appendChild(list)
关键点
appendChild/insertBefore操作已存在的节点会移动而非复制cloneNode(true)深复制包含子节点,cloneNode(false)只复制当前节点- 批量操作使用
DocumentFragment减少重排次数 querySelectorAll返回静态 NodeList,getElementsBy*返回动态 HTMLCollection- 现代 API(
append、prepend、before、after、remove)更简洁,但注意兼容性
目录