一、DOM模型概述
HTML文档只有一个根节点,而其他节点以根节点子节点或孙子节点的形式存在。最终形成一个结构化文档。DOM模型则用于导航、访问结构化文档的节点,并提供新增,修改,删除结构化本档的能力。 DOM并不是一种技术,它只是访问结构化文档(主要是XML文档和HTML文档)的一种思想。DOM解析器的作用就是完成结构化文档和DOM树之间的转换关系。通常来说,DOM解析器解析结构化文档就是将磁盘上的结构化文档转换成内存中的DOM树,而从DOM树输出结构化文档就是将内存中的DOM树转换成磁盘上的结构化文档。
如图:
二、DOM模型和HTML文档
1、HTML元素之间的继承关系
DOM为常用的HTML元素提供了一套完整的继承体系。从页面的document对象到每个常用的HTML元素DOM模型都提供了对应的类,每个类都提供了相应的方法来操作DOM元素本身属性及其子元素,DOM模型允许以树的方式操作HTML文档中的每个元素。
DOM模型里的HTML元素的继承关系:
在图14.3中,粗线框框出的4个元素:Node、Document、Element、HTMLElement都是普通HTML元素的超类,不直接对应于HTML页面控件,但它们所包含的方法也可其他页面元素调用。除此之外,还有如下常用的HTMl元素:
2、HTML元素之间常见的包含关系
有些HTML元素之间可以相互嵌套,例如<div…/>元素可以相互嵌套,但有些HTML元素则不可互相嵌套,例如<td…/>元素只能作为<tr…/>元素的子元素,<option…/>元素只能作为<select…/>元素的子元素。
下图描述了常用HTML元素之间的包含关系:
如图可以看出,HTMLDocument对象作为整个HTML文档的最大对象,里面可以包含一个HTMLBodyDocument对象。HTML文档中还有两个对象体系:表单对象和表格对象。
- 表单对象里可以包含基本的输入对象,还可以包含<select…/>元素<select…/>元素可以包含多个<option…/>元素。
- 表格对象可以包含标题(HTMLTableCaption Element)控件还可以包含多个表格行(HTMLTableCollElement)控件,每个表格行又可以包含多个单元格HTMLTableCell Element)控件。
三、访问HTML元素
为了动态的修改HTML元素,必须能访问HTML元素。DOM提供了两种方式来访问HTML元素。
- 根据ID访问HTML元素。
- 根据CSS选择器访问HTML元素。
- 根据节点关系访问HTML元素。
(前一种方式简单易用,主要有document提供的getElementById()方法来完成。后一种方式则利用树节点之间的父子兄弟关系来访问。)
1、根据ID访问HTML元素
根据id访问HTML元素如以下方法实现。document.getElementById(idval):返回文档中的id属性值为idVal的HTML元素。
上面这个方法简单易用,只要被访问的HTML元素具有唯一的id属性,那么JavaScript脚本就可以方便的访问到该元素。在设计良好的HTML页面中,建议为页面中的每个HTML元素都设置唯一的id属性值。或者要求其他成员开发HTML页面时,尽量为每个元素设置唯一的id属性值。
例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script type="text/javascript">
var accessById = function()
{
alert (document.getElementById("a").innerHTML + "\n"
+ document.getElementById("b").value);
}
</script>
</head>
<body>
<div id="a">示例</div>
<textarea id="b" cols="25" rows="3">示例1</textarea>
<input type="button" value="访问2个元素" onclick="accessById();"/>
</body>
</html>
点击按钮前后:
可能有读者感到奇怪,程序中为了访问div元素和textarea元素的内容为何一个用innerHTML属性另一个用value属性呢?这是因为DOM模型扩展了HTML元素,为几乎所有的HTML元素都新增了innerHTML元素属性,该属性代表该元素的内容----当某个元素的开始标签、结束标签都是字符串内容时,JavaScript子元素可通过它的innerHTML属性返回这些字符串内容。但是textarea例外,因为它是一个表单控件,他的开始标签和结束标签之间的内容使它的值,因此只能通过value属性来访问。不仅如此还有input元素所生成的表单控件,包括单行文本框、各种按钮等,他们的可视化文本都由value属性控制,因此也通过value来获取他们的“内容”。
2、根据CSS选择器访问HTML元素
根据CSS选择器来访问HTML元素,有document的如下方法提供支持。
- Element querySelector(selectors):该方法的参数即可是一个CSS选择器。也可以是。用逗号隔开的多个CSS选择器,该方法返回HTML文档中第一个符合选择器参数的HTML元素。
- NodeList querySelectorAll(selectors):
该方法与前一个方法的用法类似,只是该方法将返回所有符合CSS选择器的HTML元素。
对于指定了唯一的id属性值的HTML元素,即可使用前面介绍的开头element by滴方法来获取。也可以使用此处的querySelector()方法来获取此处只是要传入CSS的ID选择器即可。
例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script type="text/javascript">
var accessById = function()
{
alert (document.querySelector("#a").innerHTML + "\n"
+ document.querySelector("#b").value);
}
</script>
</head>
<body>
<div id="a">阿斯蒂芬</div>
<textarea id="b" cols="25" rows="3">在形参在</textarea>
<input type="button" value="访问2个元素" onclick="accessById();"/>
</body>
</html>
(与前一个示例基本相同)
下面示范了querySelectorALL()方法同时获取多个HTML元素的情形:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script type="text/javascript">
var change = function()
{
var divList = document.querySelectorAll("div");
console.log(divList);
for (var i in divList)
{
divList[i].innerHTML = "测试内容" + i;
divList[i].style.width= "300px";
divList[i].style.height= "50px";
divList[i].style.margin= "10px";
divList[i].style.backgroundColor = "#faa";
}
}
</script>
</head>
<body>
<div></div>
<div></div>
<div></div>
<input type="button" value="修改全部div元素" onclick="change();"/>
</body>
</html>
结果(单击按钮):
3、利用节点关系访问HTML元素
一旦获取了某个HTML元素,由于该元素实际上与DOM树的某个节点对应,因此可以利用节点之间的父子、兄弟关系来访问HTML元素。
利用节点关系访问HTML元素的属性和方法如下:
例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style type="text/css">
.selected{
background-color: #66f;
}
</style>
</head>
<body>
<ol id="books">
<li id="java">嘉大厦速度</li>
<li id="ssh">发达水电费</li>
<li id="ajax" class="selected">法规及</li>
<li id="xml">速度十多个</li>
<li id="ejb"> 森岛帆高</li>
<li id="android">阿瑟阿萨德</li>
</ol>
<input type="button" value=