写在前面:
学到DOM时,看到关于文档(结构树)、节点(node)、和DOM提供的一些方法获取(找到)所需的节点、还有DOM属性,我很混乱,我无法弄清节点的关系层级属性和方法的关系,所以在使用DOM之前我要先了解DOM,当我们用javascript对HTML DOM进行操作的时候我们要明确HTML DOM中节点类型和层级才能准确定找到你想要增删改查的位置。
找了些资料和书,看了些视频,写这篇文章总结一下自己的学习,理清一下思路。
参考:
简书-微醺岁月的《深入浅出DOM基础—DOM探索之基础详解篇》
视频-讲的挺详细老师逻辑很清晰
书籍-《JavaScript DOM编程艺术》(第2版)
1.DOM是什么?是干啥的?
DOM,文档对象模型(Document Object Model)。DOM是 W3C(万维网联盟)的标准,DOM定义了访问HTML和XML文档的标准。在W3C的标准中,DOM是独于平台和语言的接口,它允许程序和脚本动态地访问和更新文档的内容、结构和样式。
其实上面的摘抄看完也是一脸懵逼;
2.带你了解DOM
网页形成
- html为我们搭建结构使你的网页有了内容
- css来定义网页的样式,做装修让你的网页更漂亮
- JavaScript赋予了页面的行为,交互动效让你可以和网页互动
这才是完整的网页
javascript究竟通过什么来实现这些交互呢?????
有一个ECMAScript标准,基于这个标准我们可以编写程序(例如js)让浏览器来解析,在编写程序时,浏览器为我们提供了一个BOM对象(即browser object model)用来操作浏览器窗口、浏览器导航对象(navigator)、屏幕分辨率(screen)、浏览器历史(history)、cookie等等。
但这个通过BOM来实现的交互远远不够。要实现页面的动态交互和效果,操作html才是核心。
那如何操作html呢?
是htmlDOM,这时候浏览器给我们提供了DOM,DOM给我们提供了用程序(例如js)来动态控制html的接口(方法)这就是传说中的API
DOM是针对xml经过扩展用于html的应用程序编程接口,我们又叫API。
当浏览器打开网页时候,DOM把整个html页面绘制为一个多层的节点结构,html页面中的每个组成部分都是某种类型的节点,这些节点又包含着不同类型的数据。(节点(node)和数据)
然后javascript通过一些方法(例如下面会讲到)根据htmlDOM树对里面的节点(节点类型下面会介绍)进行增删改查
这是w3school提供的HTML DOM 树图片:(图1)
举个例子
下面是一个网页html(代码1)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DocumentFragment文档片段节点</title>
</head>
<body>
<!-- tip区域 -->
<div id="tip">test1</div>
<ul class="list-node">
<li>test2<li>
</ul>
<script>
var frag = document.createDocumentFragment();
for (var i = 0; i < 10; i++) {
var li = document.createElement("li");
li.innerHTML = "List item" + i;
frag.appendChild(li);
}
document.getElementById("list-node").appendChild(frag);
</script>
</body>
</html>
转换成DOM树后:(图2)
(图2)中每一个元素都是一个节点,可以看到有很多类型不同的节点。
所以:HTML DOM 节点是由多种类型的节点组合而成,所以当我们用javascript对HTML DOM进行操作的时候我们要明确HTML DOM中节点类型和层级才能准确定找到你想要增删改查的位置
节点类型
- 节点有12种类型。
下面是html DOM中常出现的类型:
类型 | 数值常量 | 字符常量 |
---|---|---|
Element(元素节点) | 1 | ELEMENT_NODE |
Attr(属性节点) | 1 | ATTRIBUTE_NODE |
Text(文本节点) | 1 | TEXT_NODE |
Comment(注释节点) | 1 | COMMENT_NODE |
Document(文档节点) | 1 | DOCUMENT_NODE |
DocumentType(文档类型节点) | 1 | DOCUMENT_TYPE_NODE |
DocumentFragment(文档片段节点) | 1 | DOCUMENT_FRAGMENT_NODE |
当使用.nodeType所的到的值就是表格中的数值常量和字符常量;可以用.nodeType(后面详解)节点类型。
此时我们知道了DOM的常用节点类型,当我们编写js代码的时候可以通过DOM提供的API(方法)对htmlDOM进行增删改查(本文不写方法的具体使用);
3,DOM的属性
每个节点都有nodeType(节点类型)、nodeName(节点名称)、nodeValue(节点值)属性(还有其他的常用属性这里不讲),我们可以通过
xxx.nodeType xxx.nodeName xxx.nodeValue
获得(xxx代表通过DOM提供的方法获取的node)
nodeType
通过某个节点的nodeType属性来获得节点类型,节点的类型可以是数值常量或者字符常量
看代码(代码2):
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>nodeType</title>
</head>
<body>
<div id="container">这是一个元素节点</div>
<script>
var divNode = document.getElementById('container');
/*
if (Node.ELEMENT_NODE || divNode.nodeType === 1) {
alert("Node is an element.");
}//通过.nodeType获取的值和节点类型的字符常量比较判断获
取的节点是什么类型
但是
IE中只支持数值常量,因为低版本IE浏览器没有内置Node对象,
其他浏览器数值常量和字符常量都支持,因此可以直接用数值
常量判断。
*/
if (divNode.nodeType == Node.ELEMENT_NODE || divNode.nodeType === 1) {
alert("Node is an element.");
}//通过.nodeType获取的值和节点类型的数值常量比较判断获取的节点是什么类型
</script>
</body>
</html>
nodeName和nodeValue
先代码(代码3):
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>nodeName,nodeValue</title>
</head>
<body>
<!--nodeName,nodeValue实验哈哈哈-->
<div id="container">这是一个元素节点</div>
<script>
var divNode = document.getElementById('container');
console.log(divNode.nodeName + "/" + divNode.nodeValue);
//结果: DIV / null
var attrNode = divNode.attributes[0];
console.log(attrNode.nodeName + "/" + attrNode.nodeValue);
//结果: id / container
var textNode = divNode.childNodes[0];
console.log(textNode.nodeName + "/" + textNode.nodeValue);
//结果: #text / 这是一个元素节点
var commentNode = document.body.childNodes[1];
//表示取第二个注释节点,因为body下面的第一个注释节点为空白符。
console.log(commentNode.nodeName + "/" +commentNode.nodeValue);
//结果: #comment / nodeName,nodeValue实验哈哈哈
console.log(document.doctype.nodeName + "/" + document.doctype.nodeValue);
//结果: html/null
var frag = document.createDocumentFragment();
console.log(frag.nodeName + "/" + frag.nodeValue);
//结果: #document-fragment / null
</script>
</body>
</html>
根据实验,得出下表格(以上面的代码为例):
节点类型 | nodeName | nodeValue |
---|---|---|
Element(元素节点) | 元素标签名称如:div | null |
Attr(属性节点) | 属性名称如:id | 属性值如:container |
Text(文本节点)#text | 节点中包含的文本内容 | |
Comment(注释节点) | #comment | 注释中的内容 |
DocumentType(文档类型节点) | doctype的名称(html) | null |
DocumentFragment(文档片段节点) | #document_fragment | null |
代码3中就用到了几个常用方法
- .getElementById通过id获取节点
- .attributes获取html标签(元素节点)的属性(也就是属性节点)可以看出属性节点是元素节点的一部分并不是父子关系
下一篇在详解DOM的更多属性和方法的使用