[JavaScript初级面试]6. WEB API - DOM(Document Object Model)

JS基础语法:ECMA 262标准
JS Web API: W3C 标准

题目

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

DOM的本质

XML(可扩展的标记描述语言)类似JSON
HTML 是一种特定的XML文件,规定了一些特定的标签名称
DOM是浏览器加载了HTML文件后,内存中生成的一个结构树

DOM节点操作

获取DOM节点

const div1 = document.getElementById('div1')     // 一个元素,id唯一
const divList = document.getElemenstByTagName('div') // 集合
const containerList = document.getElementsByClassName('.container') // 集合
const pList = document.querySelectorAll('p') // 使用css选择器 集合

attribute

可以修改HTML标签的属性,必然引起DOM重绘

const pList = document.querySelectorAll('p') 
const p1 = pList[0]
p1.setAttribute('data-name', 'test-attr')
console.log(p1.getAttribute('data-name'))

p1.setAttribute('style','font-size: 50px')
console.log(p1.getAttribute('style'))

property

以JS对象属性的形式来操作DOM节点的属性,推荐使用此方式(js有几率不让DOM重绘,但大概率还是会重绘DOM)

const pList = document.querySelectorAll('p')
const p1 = pList[0]
p1.style.width = '100px'
console.log(p1.style.width)
p1.style.className = 'red'
console.log(p1.style.className)
console.log(p1.style)
console.log(p1.nodeName) // p
console.log(p1.nodeType) // 1

DOM结构操作

新增、插入节点

const div1 = document.getElementById('div1')
// 新建节点
const newP = document.createElement('p')
newP.innerHTML = 'test p1'
div1.appendChild(newP)
// 移动节点
const div2 = document.getElementById('div2')
const p1 = document.getElementById('p1')
div2.appendChild(p1) // 从div1中移动到div2:已有节点会被移动

获取子元素列表,获取父元素

console.log(p1.parentNode)
console.log(div1.childNodes) // 可能包含其他内容

const div1ChildNodesP = Array.prototype.slice.call(div1.childNodes).filter(node => {
  if(node.nodeType === 1){ // if p
    return true
  }
  return false
}

删除子元素

const div1 = document.getElementById('div1')
const children = div1.childNodes
div1.removeChild(children[0])

DOM性能

DOM操作可能会造成浏览器重新渲染页面,需要避免频繁的DOM操作:

  • 对DOM查询做缓存
  • 对频繁修改改为一次性修改

缓存DOM查询

const list = document.getElementById('list')
// 多次插入li节点
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 < 10; i ++){
  const li = document.createElement('li')
  li.innerHTML = `List item ${i}`
  // 先插入文档片段中
  frag.appendChild(li)
}
// 一次性插入多个li
list.appendChild(frag)
posted @ 2021-09-06 10:17  Max力出奇迹  阅读(32)  评论(0编辑  收藏  举报
返回顶部↑