什么是DOM?
一开始学习JS的时候一般会花很多时间学习JavaScript的基本语法,但是这些基本语法好像和做网页没有什么关系,和前面学习的HTML、CSS也没有什么关系。这是因为我们前面学习的部分属于ECMAScript,也就是JavaScript本身的语法部分,除了语法部分之外,我们还需要学习浏览器提供给我们开发者的DOM、BOM相关的API才能对页面、浏览器进行操作。
全局对象window上事实上就包含了这些内容,Window不光包含Object、 Array、 Date等基础语法。还包含DOM、BOM部分。
DOM:文档对象模型 (Document Object Model),简称 DOM,将页面所有的内容表示为可以修改的对象。
BOM: 浏览器对象模型 (Browser Object Model),简称 BOM,由浏览器提供的用于处理文档 (document) 之外(例如浏览器本身)的所有内容的其他对象,比如navigator、 location、 history等对象。
深入理解
浏览器会对我们编写的HTML、CSS进行渲染,同时它又要考虑我们可能会通过JavaScript来对其进行操作,于是浏览器将我们编写在HTML中的每一个元素 (Element) 都抽象成了一个个对象。 所有这些对象都可以通过JavaScript来对其进行访问,那么我们就可以通过Javascript来操作页面。所以,我们将这个抽象过程称之为文档对象模型 (Document object Model)。
整个文档被抽象到 document 对象中,比如document.documentElement对应的是html元素,document.body对应的是body元素,document.head对应的是head元素。
DOM可以理解为是JavaScript和HTML与CSS之间的桥梁。
DOM的继承关系
子类具有的共同属性封装到父类中,简化了代码。OOP的核心思想这里不再赘述。
节点之间的导航(navigating nodes)
如果我们获取到一个节点 (Node) 后,可以根据这个节点去获取其他的节点,我们称之为节点之间的导航。
节点之间存在如下的关系:
- 父节点: parentNode
- 前兄弟节点: previousSibling
- 后兄弟节点: nextSibling
- 子节点: childNodes
- 第一个子节点: firstChild
- 第二个子节点: lastChild
javascript
<script>
var bodyEl = document.body
console.log(bodyEl.childNodes)
</script>
// NodeList(3)
// 0: text
// 1: script
// 2: text
// length: 3
// [[Prototype]]: NodeList
上面这段简单的示例我们可以看到,空行也属于节点,浏览器将其解析为text。
但是真实开发中我们获取类似于空行、注释这种节点没有任何意义,因此我们主要关注"元素"导航。
元素之间的导航
元素之间存在如下的关系:
- 父元素:parentElement
- 前兄弟节点:previousElementSibling
- 后兄弟节点: nextElementSibling
- 子节点: children
- 第一个子节点: firstElementChild
- 第二个子节点: lastElementChild
DOM获取任意元素的对象
尽管前面说了节点和导航的操作方法,但是这种获取对象的方法仍然有很大的弊端------太麻烦了,对于复杂的DOM Tree尤其如此。
接下来介绍JS获取DOM元素的方法(8种):
通过ID获取(getElementById)
通过name属性(getElementsByName)
通过标签名(getElementsByTagName)
通过类名(getElementsByClassName)
获取html的方法(document.documentElement)
获取body的方法(document.body)
通过选择器获取一个元素(querySelector)
通过选择器获取一组元素(querySelectorAll)
querySelector和querySelectorAll目前用的是最多的,getElementByld偶尔也会使用或者在适配一些低版本浏览器时,所以实际上掌握这两个就行了,其余的用法也不难,网上文章有很多,这里就不赘述了。
注意:当页面中存在多个相同类型的元素的时候,querySelector方法只能获取第一个元素,如果我们想获取特定位置的怎么办?实际上querySelector方法不仅可以通过document调用,也可以直接作用于元素上,例如
var boxEl = document.querySelector(".box")
var spanEl = boxEl.querySelector("span")
DOM创建元素
一开始我们学习过用document.write写入一个元素,这种方式写起来非常便捷,但是对于复杂的内容、元素关系拼接并不方便,并且真实开发中用的是很少的。之不过这是早期还没有DOM的时候采用的方案,所以仍然被保留了下来。
一般使用document.createElement方法,下面是一个简单的示例,
xml
<body>
<div id="box">
<p></p>
</div>
<script>
var boxEl = document.querySelector("#box")
var h2El = document.createElement("h2")
h2El.textContent = "hahaha"
h2El.className = "title"
boxEl.append(h2El)
</script>
</body>
不过上面这种很显然只是把DOM对象"追加"到了最后,如果我们想在其它位置(比如
元素的前面)添加元素怎么办呢?这就要用到其它的方法。
- node.append( ...nodes or strings )------在node末尾插入节点或字符串
- node.prepend(...nodes or strings)------在node 开头 插入节点或字符串
- node.before( ...nodes or strings)------在node 前面 插入节点或字符串
- node .after( ...nodes or strings)------在 node 后面 插入节点或字符串
- node.replaceWith(...nodes or strings)------将 node 替换为给定的节点或字符串