DOM与BOM

82 阅读2分钟

DOM与BOM

DOM

概念:DOM是文档对象化模型(Document Object Model)的简称。使用过DHTML对象模型的开发者一定能非常熟练地操作HTML页面上的每个标记内容,但如果借助DOM技术, 我们就可以通过更加直接而且简易的方式达到同样的目的。

DOM操作常用API

通过ID获取节点 【返回具体某个节点】:getElementById

通过标签名获取节点 【返回节点数组,即使只有一个】:getElementsByTagName

通过标签的name值获取节点 【返回节点数组】:getElementsByName

通过class值来获取节点 【返回节点数组】:getElementsByClassName

根据选择器返回找到结果集中的第一个:querySelect("选择器")

根据选择器返回找到的结果集,是个节点数组 :querySelectAll("选择器")

attribute和property的区别

来看一个简单的例子,发现一个有意思的东西:

<!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>Document</title>
  <style>
    .border {
      border: 1px solid #000;
    }
  </style>
</head>

<body>
  <div id="app">
    <p>airhua1</p>
    <p>airhua2</p>
    <p>airhua3</p>
  </div>
</body>
<script>
  const app = document.getElementById('app')
  pArr = app.children
  p1 = pArr[0]

  // property
  p1.style.color = 'red'
  p1.style.height = '200px'
  p1.className = 'border'

  // attribute
  p1.setAttribute('data-name', 'air')
  p1.setAttribute('style', 'font-size: 50px')
  console.log(p1.attributes);
</script>

</html>

1643941967371.png

可以看到通过propertyattribute都设置了style的情况下,只对attribute的style生效了。如果把两个顺序换一下看看效果。

// attribute
p1.setAttribute('data-name', 'air')
p1.setAttribute('style', 'font-size: 50px')

// property
p1.style.color = 'red'
p1.style.height = '200px'
p1.className = 'border'

1643942182175.png

发现两个style的样式叠加了,于是我去网上查了一下,原来是因为attributes是属于property的一个子集,它保存了HTML标签上定义属性

那么由此可以得到两者的区别:

  • property能够从attribute中得到同步;
  • attribute不会同步property上的值;
  • attribute和property之间的数据绑定是单向的,attribute->property;
  • 更改property和attribute上的任意值,都会将更新反映到HTML页面中;

一次性插入多个DOM节点,考虑性能

有时候我们会遇到这样的业务需求,在一个DOM节点中需要加入多个子节点,这样我们可以有各种写法,拿下面的例子来看看这两个写法的区别在哪

// ul标签
const list = document.getElementById('list')

for (let i = 0; i < 10; i++) {
  const li = document.createElement('li')
  li.innerHTML = `li ${i}`
  list.appendChild(li)
}
// 创建一个文档片段
const frag = document.createDocumentFragment()

for (let i = 0; i < 10; i++) {
  const li = document.createElement('li')
  li.innerHTML = `li ${i}`
  frag.appendChild(li)
}

list.appendChild(frag)

两段代码实现的效果是一样的,但是我们在插入DOM节点的时候需要考虑性能,因为每次修改文档内容可能会导致重排和重绘,像第一段代码就是多次直接插入html文档中,性能消耗就会比第二段中先一起放到一个文档片段中,最后一个DOM插入高。

BOM

  • navigator 浏览器信息导航对象
  • screen 浏览器屏幕对象
  • location 浏览器页面所处位置对象
  • history 浏览器浏览历史对象