前端笔记(JS-Web-API-DOM)

149 阅读2分钟

DOM(Document Object Model 文档对象模型) 操作

题目

  • DOM是那种数据结构 树(DOM树)
  • DOM操作的常用API
    • DOM节点操作:见代码演示
    • DOM结构操作:见代码演示 attribute和property操作
  • attribute和property的区别
    • 见相关知识点
  • 一次性插入多个DOM节点,考虑性能
    • 见有关知识点代码

知识点

DOM的本质

是浏览器解析HTML代码后生成的树

DOM节点的操作

获取DOM节点

 const div1 = document.getElementById('div1') //获取id 
 console.log('div1', div1)

 const divList = document.getElementsByTagName('div')  //获取标签名返回集合
 console.log('divList.length', divList.length)
 console.log('divList[1]', divList[1])

 const containerList = document.getElementsByClassName('container') //获取clss名返回集合
 console.log('containerList.length', containerList.length)
 console.log('containerList[1]', containerList[1])

 const pList = document.querySelectorAll('p') // css选择器返回集合
 console.log('pList', pList)
 
 

attribute

attribute形式是指通过获取DOM,并使用setAttribute和getAttribute在JS中修改或获取HTML标签节点属性,会改变html树

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

property

  • property形式:是指通过获取DOM,在JS中修改或获取DOM的JS属性和css样式的一种形式
  • 修改style属性会体现到DOM中,但在如p1.a =100,这类自定义属性不会体现在DOM树中。
  • property部分属性可以渲染,如 align、title、className、style
  • 但float、border、top属性又渲染不出来。
  • atribute全部都可以渲染出来。
 const pList = document.querySelectorAll('p')
 const p1 = pList[0]
 p1.style.width = '100px'
 console.log( p1.style.width )
 p1.className = 'red'
 console.log( p1.className )
 console.log(p1.nodeName)
 console.log(p1.nodeType) // 1
  • 在 DOM 阶段存储一些数据,用 props 和 attrs 还是不一样的。例如
const elem1 = document.getElementById('p1');
elem1.a = 100; // 使用 props ,不会改变 DOM 节点
elem1.setAttrbute('a', 100); // 使用 attrs ,会改变 DOM 节点

总结:

property: 适合设置自定义属性,能不需要渲染时能使用property尽量使用property attribute:适合设置标签属性,需要改变html渲染时使用

DOM结构操作

代码

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)

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

// 获取子元素列表
const div1ChildNodes = div1.childNodes
console.log( div1.childNodes )
//常规的标签即nodeType为1的标签以外的标签被过滤掉
const div1ChildNodesP = Array.prototype.slice.call(div1.childNodes).filter(child => {
    if (child.nodeType === 1) {
        return true
    }
    return false
})
console.log('div1ChildNodesP', div1ChildNodesP)
//删除标签
div1.removeChild( div1ChildNodesP[0] )

DOM性能

  • DOM操作非常消耗资源,避免频繁的DOM操作
  • 对DOM查询做缓存
// 不缓存DOM查询结果
for (let = 0;i<document.getElementsByTagName('p').length;i++){
    //每次循环,都会计算length,频繁进行DOM查询
}
// 缓存DOM查询结果
const pList = document.getElementByTagName('p')
const length = pList.length
for (let i = 0; i <length; i++){
    //缓存 length, 只进行一次DOM查询 
}
  • 将频繁操作改为一次性操作
const list = document.getElementById('list')

// 创建一个文档片段,此时还没有插入到 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)
}

// 都完成之后,再统一插入到 DOM 结构中
list.appendChild(frag)

console.log(list)