1. DOM的本质
DOM(Document Object Model),文档对象模型。DOM的本质是从HTML文件中解析出来的一棵树。DOM的数据结构是树形结构(DOM树)
2. DOM节点操作
2.1 获取DOM节点
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>获取DOM节点</title>
<style>
.container{border: 1px solid red; width: 200px;}
</style>
</head>
<body>
<div id="div1" class="container">
<p>一段文字1</p>
<p>一段文字2</p>
</div>
<div id="div2" class="container">
<p>一段文字3</p>
<p>一段文字4</p>
</div>
<script>
// getElementById
const div1 = document.getElementById('div1')
console.log('div1', div1)
// getElementsByTagName
const divList = document.getElementsByTagName('div')
console.log('divList', divList)
console.log('divList.length', divList.length)
console.log('divList[0]', divList[0])
// getElementsByClassName
const containerList = document.getElementsByClassName('container')
console.log('containerList', containerList)
console.log('containerList.length', containerList.length)
console.log('containerList[0]', containerList[0])
// querySelectorAll
const pList = document.querySelectorAll('p')
console.log('pList', pList)
</script>
</body>
</html>
2.2 property
property:修改对象属性,不会体现到html结构中。
// querySelectorAll
const pList = document.querySelectorAll('p')
console.log('pList', pList)
const p = pList[0]
console.log(p.style.width)
console.log(p.className)
p.style.width = '100px'
p.className = 'p1'
console.log(p.style.width)
console.log(p.className)
2.3 attribute
attribute:修改html属性,会改变html结构。
property和attribute都会引起DOM重新渲染。
// attribute
const p1 = pList[1]
p1.setAttribute('data-name', 'imooc')
console.log(p1.getAttribute('data-name'))
p1.setAttribute('style', 'font-size:30px;')
console.log(p1.getAttribute('style'))
3. DOM结构操作
3.1 插入新的节点
// 新建节点
const newP = document.createElement('p')
newP.innerHTML = 'this is newP'
newP.className = 'newP'
// 插入节点
div1.appendChild(newP)
3.2 移动已有的节点
// 移动已有节点
const div2 = document.getElementById('div2')
div2.appendChild(p1)
3.3 获取子元素列表
const div1Child = div1.childNodes
console.log(div1Child)
通过判断nodeType,可以取出p标签,nodeType === 1
表示p标签
const div1ChildP = Array.prototype.slice.call(div1.childNodes).filter(a=>{
if(a.nodeType === 1){
return true
}
return false
})
console.log(div1ChildP)
3.4 获取父元素
console.log(p1.parentNode)
3.4 删除节点
div1.removeChild(div1ChildP[0])
4. 优化DOM操作性能
DOM操作会占用较多CPU,频繁操作会导致卡顿。
解决方案:
- 对DOM查询做缓存
- 频繁操作改为一次性操作
4.1 对DOM查询做缓存
4.2 频繁操作改为一次性操作
新建10个li,频繁操作的情况:
<body>
<ul id="list">
</ul>
<script>
const list = document.getElementById('list')
for(let i =0; i < 10; i++){
const li = document.createElement('li')
li.innerHTML = `List item ${i}`
list.appendChild(li)
}
</script>
</body>
改为一次性操作:
const list = document.getElementById('list')
// 首先,创建一个文档片段,没有插入到DOM结构中
const frag = document.createDocumentFragment()
for(let i =0; i < 10; i++){
const li = document.createElement('li')
li.innerHTML = `List item ${i}`
// 然后,再文档片段中插入DOM元素
frag.appendChild(li)
}
// 最后,统一插入到DOM结构中
list.appendChild(frag)