JS_DOM
Javascript DOM
一、文档对象模型DOM
(一)理解DOM的作用
JS中的文档对象模型DOM(Document Object Model)的意义实际上是为了使用JS来操纵HTML页面,DOM将HTML文档中每个结点“映射”为一个对象,然后就可以在JS中使用面向对象的思维去操纵页面以及页面中的结点。HTML与DOM之间的关系可以理解为操作DOM就可以改变HTML页面的内容文档结构,而为HTML页面添加标签的话DOM也会作出一样的变化。将标签(HTML)“映射”为对象(JS)之后用JS操作对象的属性与方法,进而改变HTML的内容。DOM操作HTML结点,两者之间是相互映射的关系
Document:整个HTML页面文档
Object:将网页的每一部分转换为了一个对象(p标签、a标签…)
Model:使用模型来表示(结点/)对象之间的关系
(二)结点层次与常用结点
(1)结点层次
结点层次分为Node类型、Document类型、Element类型、Text类型、Comment类型、CDATA类型、DocumentType类型、DocumentFragment类型、Attr类型。
(2)结点的属性
每种类型的结点都会有nodeName、nodeType、nodeValue三种属性,随着结点类型的不同这三个属性的值也不尽相同。
(3)常用结点
结点是构成网页的基本组成部分,网页中的每个部分都可以看成是一个结点,比如HTML标签、属性、文本、整个文档都可以看成一个结点。但是这些结点的具体类型是不一样的,结点的属性与方法也不一样。每个节点可以看成是一个对象。(高程三里面称这些节点是对象)
Document类型结点
document对象是HTMLDocument(继承自Document类型)的一个实例,同时document对象是window对象的一个属性,通过文档对象可以获取页面有关的信息(获取页面title),还可以操作页面的外观(使用JS改变样式)以及操作底层结构(使用JS改变HTML文档结构)
document类型的查找元素是DOM最常用的一个方面,用于获取特定某个(组)元素的引用,然后再执行一些操作,通过document对象的一些方法来完成页面元素的查找。返回的是对应HTML文档对应DOM中的结点对象的引用
_1:**document.getElementById() ** ,通过元素id获取结点元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20<!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>
</head>
<body>
<button id="btn">我是一个按钮</button>
</body>
<script>
var btn = document.getElementById("btn");
console.log(btn.innerHTML); //我是一个按钮
console.log(btn); //<button id="btn">我是一个按钮</button>
console.log(typeof btn); //object
btn.innerHTML = "I'm Button"; //按钮的内部文本改变为I'm Button
</script>
</html>_2:document.getElementsByTagName() ,通过标签名获取文档中所有的该名节点元素,返回nodeList,可以通过返回的nodeList用类似数组的方式访问这些标签的属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21<!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>
</head>
<body>
<img src="123">
<img src="231">
<img src="321">
</body>
<script>
var images = document.getElementsByTagName("img");
console.log(images);//HTMLCollection(3) [img, img, img]
console.log(images.length);//3
console.log(images[0].src);// 一长串的文件路径 /123
console.log(images.item(1).src);// 一长串的文件路径 /231
</script>
</html>Element类型结点
Element对象用于访问HTML元素标签名、子节点以及属性
_1:访问元素标签名
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17<!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>
</head>
<body>
<div id="myDiv"></div>
</body>
<script>
//使用文档类型获取div结点的引用,获取到的是Element类型的元素
var myDiv = document.getElementById("myDiv");
console.log(myDiv.tagName); //DIV 获取标签名
</script>
</html>_2:获取结点属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20<!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>
</head>
<body>
<div id="myDiv"></div>
</body>
<script>
//使用文档类型获取div结点的引用,获取到的是Element类型的元素
var myDiv = document.getElementById("myDiv");
console.log(myDiv.tagName); //DIV 获取标签名
console.log(myDiv.getAttribute("id")); //myDiv
myDiv.id = "herDiv"; //修改节点属性值
console.log(myDiv.getAttribute("id")); //herDiv
</script>
</html>_3:创建元素
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25<!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>
</head>
<body>
<div id="myDiv"></div>
</body>
<script>
var div = document.createElement("div"); //创建div结点
div.id = "isDIV";
console.log(div); // <div id="isDIV"></div>
console.log(typeof div); // object
console.log(div.id); //isDIV
/*
理解DOM与HTML文档结点的关系:使用方法创建的div方法返回的是一个对象,
这从另一个角度看出HTML文档的结点对应着DOM里面的一个对象
*/
/*通过ceateElement方法创建的HTML结点元素并没有挂载到HTML页面上,
要通过其他的方法挂载*/
</script>创建结点并挂载到HTML文档
1
document.body.appendChild(div);
_4:元素子节点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28<!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>
</head>
<body>
<ul id="myList">
<li>item 1</li>
<li>item 2</li>
<li>item 3</li>
<li>item 4</li>
</ul>
</body>
<script>
var myUl = document.getElementById("myList");
console.log(myUl); //输出HTML元素结点
console.log(myUl.childNodes.length); //9 4个<li> 4个文本 还有一个空白符(空格)
for(let i=0;i<myUl.childNodes.length;i++){
console.log(myUl.childNodes[i].nodeType); // 3 1 3 1 ...
}
console.log(myUl instanceof Object); //true
console.log(myUl.childNodes instanceof Array); //false
console.log(typeof myUl.childNodes); //object 并不是一个数组,而是一个对象
</script>
</html>Text类型结点(纯文本内容)
_1:创建文本结点并修改文本内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23<!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>
</head>
<body>
<div id="isDIV">Hello guys</div>
</body>
<script>
// 创建一个元素并为这个元素添加文本结点,然后挂载到页面上
var myDIV = document.createElement("div"); //创建div结点
myDIV.className = "myDIV"; //设置class名
var textNode = document.createTextNode("Hello my friend"); //创建结点元素
myDIV.appendChild(textNode); //将创建好的结点元素加载到DIV里面
document.body.appendChild(myDIV); //将包装有文本结点的DIV挂载到页面上
var isDIV = document.getElementById("isDIV");
isDIV.firstChild.nodeValue = "Hello Morant!"; //修改已有结点的text文本
</script>
</html>_2:分割文本结点 (将一个文本结点分裂成两个文本结点)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23<!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>
</head>
<body>
</body>
<script>
var tNode = document.createTextNode("Hello Guys");
console.log(tNode.nodeValue); //Hello Guys
var _tNode = tNode.splitText(5);
console.log(tNode); // "Hello"
console.log(_tNode); // "Guys"
console.log(typeof tNode); // "object"
console.log(typeof _tNode); // "object"
</script>
</html>Comment类型:DOM中注释也看成一个结点对象
CDATASection类型:只针对于XML文档
DocumentType类型、DocumentFragment类型。
Attr类型:结点元素的属性也看做是一个对象,nodeName是属性名,nodeValue是属性值
(三)DOM操作技术
(1)动态脚本
在页面加载时这段JS脚本是不存在的,当某些操作之后通过修改DOM触发动态生成脚本。(比如有一段JS代码需要某些操作之后才加载,这里的DOM思路是将外部写好的JS代码通过DOM动态生成HTML的script标签将其引入HTML文档中事项动态脚本);
_1:动态加载外部JS代码
1 |
|
_2:上面的JS标签结点对应的DOM代码
1 |
|
ps: 这里应该更加理解DOM和HTML之间的关系,而不仅仅是直到有document那几个方法,DOM和HTML之间的关系是相互”映射”之间的关系,用不同的方式描述着同样的内容,HTML加入一个结点,DOM树对应地也加入了一个结点,DOM用代码的方式也可以为HTML文档加入HTML结点标签
(2)动态样式
同样的类似于创建动态脚本一样,也可以使用DOM来动态引入CSS样式,有两种方法,一种是类似于上面的方式外部写好的CSS动态创建标签引入样式表;另一种方式是用DOM实现嵌入式(直接写在HTML页面文档中)样式。(link引入外部CSS,style标签写嵌入式)
_1:动态加载外部样式表
1 |
|
上面的JS标签结点对应的DOM代码
1 |
|
_2:DOM实现嵌入式CSS
1 |
|
上面的CSS标签结点对应的DOM代码
1 |
|
(3)操作表格
JS的DOM代码动态创建表格比直接使用HTML标签创建要多得多,感觉在日常开发中会很少用到,但是要用到的话直接上网找就好了
(4)使用NodeList、NamedNodeMap、HTMLCollection
DOM是JavaScript重要组成部分,在DOM中有三个特别的集合分别是NodeList(节点的集合),NamedNodeMap(元素属性的集合)和HTMLCollection(html元素的集合)。这三个集合有一些共同的特点:它们都可以通过中括号表达式来访问集合中元素,也有length属性。但它们并不是数组,而且它们都是动态的,会根据页面元素的变化而变化(类数组对象)
https://blog.csdn.net/u012207345/article/details/78165931
DOM操作是JS程序中开销最大的,会对程序的性能产生比较大的影响,尽量减少DOM操作
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!