# DOM
前言
- vue 和 react 框架应用广泛,封装了DOM操作
- 但DOM操作一直都是前端工程师的基础,必备知识
- 只会vue 而不懂 DOM 操作的前端,不会长久
注重基础
# DOM操作(Document Object Model)
- DOM本质
- DOM节点操作
- DOM结构操作
- DOM性能
# DOM本质
类似XML HTML
DOM 本质是一颗树
# DOM节点操作
- 获取DOM节点
const div1 = document.getElementById('div1') // 元素
const divList = document.getElementByTagName('div') // 集合
console.log(diconsole.log()
console.log(divList[0])
const containerList = document.getElementByClassName('.container') // 集合
const pList = document.querySelectorAll('p') // 集合
- DOM节点的attribute: 修改html 属性,会改变html结构
const pList = document.querySelectorAll('p')
const p = pList[0]
p.getAttribute('data-name')
p.setAttribute('data-name', 'aa')
p.getAttribute('style')
p.setAttribute('style', 'font-size: 40px;')
- DOM节点的property:修改对象属性,不会体现到html结构中
const pList = document.querySelectorAll('p')
const p = pList[0]
console.log(p.style.width) // 获取样式
p.style.width = '100px' // 修改样式
console.log(p.className) // 获取class
p.className = 'p1' // 修改 class
// 获取nodeName 和 nodeType
console.log(p.nodeName)
console.log(p.nodeType)
# attribute VS property
- attribute:修改 html 属性,会改变 html 结构
- property:修改对象属性,不会体现到 html 结构
- 两者都有可能引起DOM重新渲染
# DOM结构操作
- 新增/插入节点
const div1 = document.getElementById('div1')
// 添加新节点
const p1 = document.createElement('p')
p1.innerHTML = 'this is p1'
div1.appendChild(p1) // 添加新创建的元素
// 移动已有节点,注意是移动!!!
const p2 = document.getElementById('p2')
div1.appendChild(p2)
- 获取子元素列表,获取父元素
// 获取子元素列表
const div1 = document.getELementById('div1')
const child = div1.childNodes
// 获取父元素
const div1 = document.getELementById('div1')
const parent = div1.parentNode
- 删除节点
const div1 = document.getELementById('div1')
const child = div1.childNodes
div1.removeChild(cjild[0])
# DOM频繁操作性能优化
# DOM 性能
- DOM操作非常昂贵,避免频繁的DOM操作
- 对DOM查询做缓存
- 将频繁操作改为一次性操作
# DOM 查询做缓存
// 不缓存DOM 查询结果
for (let i = 0; i < document.getELementByTagName('p').length; i++) {
// 每次循环,都会计算length,频繁进行 DOM 查询
}
// 缓存 DOM 查询结果
const pList = document.egtElementByTagName('p')
const len = pList.length
for (let i = 0; i < len; i++) {
// 缓存length , 只进行一次DOM 查询
}
# 将频繁操作改为一次性操作
const listNode = docuemnt.egtElementById('list')
// 创建一个文本片段,此时还没有插入到DOM树中
const frag = document.createDocumentFragment()
// 执行插入
for (let x = 0; x < 10; x++) {
const li = document.createElement('li')
li.innerHYML = 'List item' + x
frag.appendChild(li)
}
// 都完成之后,再插入到DOM数中
listNode.appendChild(frag)