目录
DOM(Document Object Model)文档对象模型,是JS操作网页的接口。用于将网页转为一个JS对象,从而可以用脚本进行各种操作(比如增删内容)。
文档:表示的就是整个的HTML网页文档
对象:表示将网页中的每一个部分都转换为了一个对象。
模型:表示对象之间的关系,这样方便我们获取对象
文档对象模型(DOM)是网页的编程接口。它给文档(结构树)提供了一个结构化的表述并且定义了一种方式——程序可以对结构树进行访问,以改变文档的结构,样式和内容。
1.节点层级
任何 HTML 或 XML 文档都可以用 DOM 表示为一个由节点构成的层级结构。节点分很多类型,每种类型对应着文档中不同的信息和标记,有自己不同的特性、数据和方法,而且与其他类型有某种关系。这些关系构成了层级,让标记可以表示为一个以特定节点为根的树形结构。
<!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>Hello DOM</title>
</head>
<body>
<p>Hello DOM</p>
</body>
</html>
在 XML 文档中,则没有这样预定义的元素,任何元素都可能成为文档元素。
1.2.节点
DOM的最小组成单位叫做节点(node)。
节点的类型有七种:Document、DocumentType、Element、Text、Comment、DocumentFragment。
(1)常用节点
文档节点(document):整个HTML文档document对象作为window对象的属性存在的,可以直接使用。
元素节点(Element):HTML文档中的HTML标签。
属性节点(Attribute):元素的属性,即标签中的属性,这里要注意的是属性节点并非是元素节点的子节点,而是元素节点的一部分。
文本节点(Text):标签中的文本内容。
(2)其他节点
DocumentType:doctype标签(比如<!DOCTYPE html>)。
Comment:注释
DocumentFragment:文档的片段
这七种节点都属于浏览器原生提供的节点对象的派生对象,具有一些共同的属性和方法。
1.3节点树
一个文档的所有节点,按照所在的层级,可以抽象成一种树状结构。这种树状结构就是DOM。文档的树形结构(DOM树),就是由各种不同类型的节点组成。每个节点可以看作是文档树的一片叶子。
上面案例的节点数,如图:
除了根节点以外,其他节点对于周围的节点都存在三种关系。DOM提供操作接口,用来获取三种关系的节点。
父节点关系(parentNode):直接的上级节点。
子节点关系(childNode):直接的下级节点。子节点接口包括firstChild(第一个子节点)和lastChild(最后一个子节点)等属性。
同级节点关系(sibling):拥有同一父节点的节点。同级节点接口包括nextSibling(紧邻在后的那个同级节点)和previousSibling(紧邻在前的那个同级节点)属性。
2.节点(Node)类型
DOM Level1描述了名为Node的接口,这个接口是所有DOM节点类型都必须实现的。Node接口在 JavaScript中被实现为Node类型,在除 IE之外的所有浏览器中都可以直接访问这个类型。在 JavaScript中,所有节点类型都继承Node类型,因此所有类型都共享相同的基本属性和方法。
2.1属性
(1)nodeType属性
作用:表示节点的类型
节点类型 | 值 |
文档节点(document) | 9 |
元素节点(Element) | 1 |
属性节点(Attr) | 2 |
文本节点(Text) | 3 |
文档类型节点(DocumentType) | 10 |
注释节点(Comment) | 8 |
文档片段节点(DocumentFragment) | 11 |
<div id="div1"></div>
<script>
console.log(document.nodeType);//9
console.log(div1.nodeType);//1
</script>
(2)nodeName属性
作用:返回节点的名称
<div id="div1">hello world</div>
<script>
var div = document.getElementById('div1');
console.log(div.nodeName); //DIV
console.log(div.firstChild.nodeName); //#text
</script>
(3)nodeValue属性
作用:可读写当前节点本身的文本值。只有文本节点、注释节点和属性节点有文本值
<div id="div1">hello world</div>
<script>
var div = document.getElementById('div1');
console.log(div.nodeValue); // null
// 读
console.log(div.firstChild.nodeValue); //hello world
// 写
div.firstChild.nodeValue = '123';
console.log(div.firstChild.nodeValue);//123
</script>
(4)textContent属性
作用:返回当前节点和它的所有后代节点的文本内容
<div id="div1">Hello <span><span>World </span>JavaScript</span> DOM</div>
<script>
var div = document.getElementById('div1');
console.log(div.textContent); //Hello World JavaScript DOM
</script>
(5)nextSibling属性
作用:返回紧跟当前节点后面的第一个同级节点。如果没有返回null
<div id="div1">hello</div>
<div id="div2">world</div>
<script>
var d1 = document.getElementById('div1');
var d2 = document.getElementById('div2');
console.log(d1.nextSibling); //#text "\n " 没有得到预想的结果是因为第二个div换行了,紧跟当前节点的第一个同级节点不再是第二个div
console.log(d1.nextSibling === d2); // false
</script>
<div id="div1">hello</div><div id="div2">world</div>
<script>
var d1 = document.getElementById('div1');
var d2 = document.getElementById('div2');
console.log(d1.nextSibling); //<div id="d2">world</div>
console.log(d1.nextSibling === d2); // true
</script>
(6)previousSibling属性
作用:返回当前节点前面的、距离最近的一个同级节点。如果没有返回null
<div id="div1">hello</div><div id="div2">world</div>
<script>
var d1 = document.getElementById('div1');
var d2 = document.getElementById('div2');
console.log(d1.previousSibling); //<div id="div1">hello</div>
console.log(d1.previousSibling === div1); // true
</script>
(7)parentNode属性
作用:返回当前节点的父节点。它的父节点只可能是三种类型:元素节点、文档节点和文档片段节点
<div id="d1">hello world</div>
<script>
var div1 = document.getElementById('d1');
console.log(div1.parentNode); // body
</script>
(8)parentElement属性
作用:返回当前节点的父元素节点。如果当前节点没有父元素节点,则返回null
<div id="d1">hello world</div>
<script>
var div1 = document.getElementById('d1');
console.log(div1.parentElement); // <body>
//设置父元素的样式属性
div1.parentElement.style.color= 'red';
</script>
(9)firstChild&lastChild
作用:返回当前节点的第一个/最后一个子节点,如果当前节点没有子节点,则返回null
<div id="d1">子节点1<div>div</div></div>
<script>
var div1 = document.getElementById('d1');
console.log(div1.firstChild); // #text "子节点1"
console.log(div1.lastChild); // <div>
</script>
(10)childNodes属性
作用:返回当前节点的所有子节点,返回结果为数组类型
<div id="d1">子节点1<div>div</div></div>
<script>
var div1 = document.getElementById('d1');
console.log(div1.childNodes); //NodeList [ #text, div ]
</script>
3.方法
(1)appendChild()
作用:添加子节点。用于将接受的节点对象作为最后一个子节点,插入当前节点
传入参数:节点对象 返回值:插入文档的子节点
<body id="box">
<script>
// 创建元素节点p
var p = document.createElement('p');
// 向p标签插入内容
p.innerHTML = '我是一个p标签';
// 将节点插入到body中
document.body.appendChild(p);
//查看body的所有子节点,验证是否插入成功
res = document.getElementById('box');
console.log(res.childNodes);//NodeList(3) [ #text, script, p ]
</script>
</body>
(2)insertBefore()
作用:用于将某个节点插入父节点内部的指定位置
var insertedNode = parentNode.insertBefore(newNode, referenceNode);
语法:insertBefore(newNode,referenceNode) newNode&referenceNode传入的参数
newNode:表示所要插入的节点,插入的位置是referenceNode的前面
referenceNode:当前节点的父节点内部的某个子节点
返回值:newNode
<div id="div1">我是div1</div>
<div id="div2">我是div2</div>
<div id="div3">我是div3</div>
<script>
//创建一个p标签
var newNode = document.createElement("p");
// 向p标签插入内容
newNode.innerHTML = '我是p标签'
//parentNode.insertBefore(newNode, referenceNode);
// 获取要插入位置的节点
var refer = document.getElementById('div2')
// 获取父节点的引用
var father = refer.parentNode
// 插入节点
father.insertBefore(newNode,refer)
</script>
(3)removeChild()
作用:接受一个子节点作为参数,用于从当前节点移除该子节点
返回值:移除的子节点
//移除div2
<div id="div1">我是div1</div>
<div id="div2">我是div2</div>
<div id="div3">我是div3</div>
<script>
// 获取要删除的节点的引用
var refer = document.getElementById('div2')
// 获取删除的节点的父节点的引用
var father = refer.parentNode
// 删除该子节点
father.removeChild(refer)
</script>
(4)replaceChild()
作用:用于将一个新的节点,替换当前节点的某一个子节点
语法: parentNode.replaceChild(newNode, replaceNode)
replaceNode:要替换的节点
newNode:用于替换的新节点
parentNode:要替换的节点的父节点
//替换div2
<div id="div1">我是div1</div>
<div id="div2">我是div2</div>
<div id="div3">我是div3</div>
<script>
// 创建一个p标签
var p = document.createElement('p');
// 向P标签插入内容
p.innerHTML = '我是一个p标签'
// 获取要替换的节点的引用
var replace = document.getElementById('div2')
// 获取替换的节点的父节点的引用
var father = replace.parentNode
// 删除该子节点
father.replaceChild(p,replace)
</script>
注意:以上四个方法均需要对父节点对象进行调用