JS Web API
- JS基础知识是规定语法(ECMA262标准)
- JS Web API,网页操作的API(W3C标准)
- 前者是后者的基础,两者结合才能真正实际应用
JS web API的范围
- DOM操作
- BOM操作
- 事件绑定
- ajax
- 存储
DOM的本质DOCUMENT OBJECT MODEL
- vue和React框架应用广发,封装了DOM操作
- 但是DOM操作是前端工程师的基础,必备基础知识
- 只会VUE和React的前端工程师是不够的
题目:
- DOM是那种数据结构
- DOM操作常用的API
- attr和property的区别
- 一次性插入多个DOM节点,考虑性能
知识点
- DOM本质
- DOM节点操作
- DOM结构操作
- DOM性能
DOM 本质
<?xml version="1.0" encoding"=UTF-8"?>
<note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
<other>
<a></a>
<a></a>
</other>
</note>
看一下以上的xml,可以自己定义标签,可以任意扩展
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div>
<p>this is p</p>
</div>
</body>
</html>
以上是html的示范,结构和xml相似,但是有自己的规定
DOM的本质是一颗树的结构,比如打开浏览器的开发者模式,看到elements,就可以看到这颗树的结构。但是浏览器下的DOM不是DOM,因为还有CSS。
DOM节点操作
- 获取DOM节点
- attribute
- property
如何获取DOM节点
const div1=document.getElementById('div1') //元素
const divList = document.getElementsByTagName('div') // 集合
console.log(divList.length)
console.log(divList[0])
const containerList = document.getElementByClassName('.container') //集合
const pList =document.querySelectorAll('p') // 集合
DOM节点的property,修改的是js变量的属性,不会体现到HTML结构中
const pList = document.querySelectorAll('p');
const p = pList[0]
console.log(p.style.width) // 获取样式
p.style.width = '100px' //修改样式
console.log(p.className) //获取样式
p.className = 'p1' //修改 class
// 获取nodeName和nodeType
console.log(p.nadeName)
console.log(p.nodeType)
DOM节点的attribute,能真正作用到DOM里去,会改变html
const pList = document.querySelectorAll('p')
const p = pList[0]
p.getAttribute('dattta-name')
p.setAttribute('data-name','imooc')
p.getAttribute('sytle')
p.setAttribute('style','font-size:30px;')
property和attribute都会引起DOM重新渲染
DOM 结构操作
- 新增/插入节点
- 获取子节点列表,获取父节点
- 删除子节点
console.log('dom2')
const div1 = document.getElementById('div1')
const div2 = document.getElementById('div2')
//新建节点
const p1 = document.createElement('p')
p1.innerHTML = 'this is p1'
//插入节点
div1.appendChild(p1)
//移动节点
const p2 = document.getElementById('p2')
div2.appendChild(p2)
获取子元素列表
const div1= document.getElementById('div1')
const child = div1.childNodes
获取父元素
const div1 = document.getElementById('div1')
const parent =div1.parentDode
删除节点
const div1= document.getElementById('div1')
const child = div1.childNodes
div1.removeChild(child[0])
DOM性能
- DOM操作非常昂贵的:耗时,占用CPU计算,所以要尽量避免频繁的DOM操作,可能会卡顿
- 对DOM查询做缓存
- 将频繁操作改为一次性操作
DOM查询做缓存
//不缓存DOM查询结果
for(let =0;i<document.getElementsByTagName('p').length;i++){
//每次循环,都会计算length,频繁进行DOM查询
}
const pList = document.getElementsByTagName('p')
const length = pList.length
for(let i =0;i<length;i++){
//缓存了length,只进行一次DOM查询
}
将频繁操作改为一次性操作
const listNode =document.getElementById('list');
//创建一个文档片段,此时还没插入到DOM树中
const frag =document.createDocumentFragment()
//执行插入
for(let x = 0;x<10;x++){
const li = document.createElement("li")
li.innerHTML ="List item"+x
frag.appendChild(li)
}
//都完成之后,再插入DOM树中
listNode.appendChild(frag)
console.log('dom3.js');
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)
} */
//不应该在循环里插入
//将频繁操作改为一次性操作
//创建一个文档片段,此时还没插入到DOM树中
const frag =document.createDocumentFragment()
//执行插入
for (let i=0;i<20;i++){
const li = document.createElement('li');
li.innerHTML =`list item ${i}`
//先插入文档片段
frag.appendChild(li)
list.appendChild(frag)
}
DOM常用API
DOM 结构和DOM 节点, DOM attribute 和property,尽量使用property