9-JS-WEB-API

197 阅读2分钟

JS Web API

  • DOM
  • BOM
  • 事件绑定
  • ajax
  • 存储

DOM操作

题目

- DOM是哪种数据结构
- DOM操作的常用API
- attr和property的区别
- 一次性插入多个DOM节点,考虑性能
  • DOM是哪种数据结构

    • 树(DOM树)
  • DOM操作的常用API

    • DOM节点操作(自己列一下)
    • DOM结构操作
    • attribute和property
  • attr和property的区别

    • property:修改对象属性,不会体现到html结构中
    • attribute:修改html属性,会改变html结构
    • 两者都有可能引起DOM重新渲染(尽量只使用property)
    • 详细区别参考JS中attribute和property的区别
  • 一次性插入多个DOM节点,考虑性能

    • 参考下面的DOM性能

知识点

  • DOM本质
  • DOM节点操作
  • DOM结构操作
  • DOM性能

DOM本质

DOM本质是一颗树

image.png

image.png

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.getElementsByClassName('.container') //集合
const pList = document.querySelectorAll('p') //集合

DOM节点的property

const pList = document.querySelectorAll('p')
const p = pList[0]
p.style.width = '100px' //修改样式
console.log(p.style.width) //获取样式
p.className = 'p1'  //修改calss
console.log(p.className) //获取class

//获取nodeName 和 nodeType
console.log(p.nodeName)
console.log(p.nodeType)

DOM节点的attribute

const pList = document.querySelectorAll('p')
const p = pList[0]
p.getAttribute('data-name')
p.setAttribute('data-name','imooc')
p.getAttribute('style')
p.setAttribute('style','font-size:30px;')

property和attribute

  • property:修改对象属性,不会体现到html结构中
  • attribute:修改html属性,会改变html结构
  • 两者都有可能引起DOM重新渲染
  • 详细区别参考JS中attribute和property的区别

DOM结构操作

  • 新增/插入节点
  • 获取子元素列表,获取父元素
  • 删除子元素
<body>
    <div id="div1">
        <p id="p1">一段文字1</p>
        <p>一段文字2</p>
        <p>一段文字3</p>
    </div>
    <div id="div2">    </div>
</body>
<script>
const div1 = document.getElementById('div1')
const div2 = document.getElementById('div2')

//新建节点
const newP = document.createElement('p')
newP.innerHTML = 'this is newP'
//插入节点
div1.appendChild(newP)

//移动节点  !!移动现有节点是移动!!
const p1 = document.getElementById('p1')
div2.appendChild(p1)
</script>

获取子元素列表&获取父元素&删除子节点

//获取父元素
console.log(p1.parentNode)

//获取子元素列表
const div1childNodes = div1.childNodes;
console.log(div1.childNodes)
const div1ChildNodesP = Array.prototype.slice.call(div1.childNodes).filter(child => {
    //childNodes里面会有一些文本节点等
    if(child.nodeType === 1){
        return true
    }
    return false
})
console.log('div1ChildNodesP',div1ChildNodesP)

//删除子节点
const div1 = document.getElementById('div1')
const child = div1.childNodes
div1.removeChild(child[0])

DOM性能

  • DOM操作非常“昂贵”,避免频繁的DOM操作
  • 对DOM查询做缓存
  • 将频繁操作改为一次性操作

DOM查询做缓存

//不缓存DOM查询结果(不推荐使用)
for(let i = 0; i < document.getElementsByTagName('p').length;i++){
    //每次循环,都会计算length,频繁进行DOM查询
}

//缓存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树中

错误未范频繁操作(不推荐)

const list = document.getElemetById('list')
for(let i = 0; i < 10; i++){
    const li = document.createElement('li')
    li.innerHTML = 'List item' + i
    list.appendChild(li)
}