Java-DOM

概述

DOM:Document Object Model(文档对象模型)

  • 用来将标记型文档封装成对象,并将标记型文档中的所有的内容(标签,文本,属性等)都封装成对象。
  • 封装成对象的目的是为了更为方便的操作这些文档以及文档中的所有内容。
  • 因为对象的出现就可以有属性和行为被调用。

文档对象模型

  • 文档:标记型文档
  • 对象:封装了属性和行为的实例,可以被直接调用
  • 模型:所有标记型文档都具备一些共性特征的一个体现

标记型文档(标签,属性,标签中封装的数据)

  • 只要是标记型文档,DOM这种技术都可以对其进行操作
  • 常见的标记型文档:html xml
  • DOM这种技术是如何对标记型文档机型操作的呢?
    • 要操作标记型文档必须对其进行解析

解析方式

DOM

  • DOM技术的解析方式:
    • 将标记型文档解析一棵DOM树,并将树中的内容都封装成节点对象
  • DOM解析方式
    • 好处:可以对树中的节点进行任意操作,比如:增删改查
    • 弊端:这种解析需要将整个标记型文档加载进内存。
      • 意味着如果标记型文档的体积很大,较为浪费内存空间

SAX

  • SAX:是由一些组织定义的一种民间常用的解析方式,并不是w3c标准,而DOM是W3C的标准
  • SAX解析的方式:基于事件驱动的解析。获取数据的速度很快,但是不能对标记进行增删改

DOM三级模型

  • DOM level 1:将html文档封装成对象
  • DOM level 2:在level 1基础上加入了新功能,比如解析名称空间
  • DOM level 3:将xml文档封装成了对象

DHTML

动态的HTML,不是一门语言,是多项技术综合体的简称

其中包含了HTML,CSS,DOM,JavaScript

  • 这四个技术在动态html页面效果定义时,都处于什么样角色呢?负责什么样的职责呢?
  • HTML:
    • 负责提供标签,对数据进行封装,目的是便于对该标签中的数据进行操作
    • 简单说:用标签封装数据
  • CSS:
    • 负责提供样式属性,对标签中的数据进行样式的定义
    • 简单说:对数据进行样式定义
  • DOM:
    • 负责将标签型文档以及文档中的所有内容进行解析,并封装成对象,
    • 在对象中定义了更多的属性和行为,便于对对象操作
    • 简单说:将文档和标签以及其他内容变成对象
  • J s:
    • 负责提供程序设计语言,对页面中的对象进行逻辑操作
    • 简单说:负责页面的行为定义,就是页面的动态效果
  • 所以 JavaScript是动态效果的主力编程语言
  • DHTML+XMLhttpRequest = AJAX

BOM

Browser Object Model 浏览器对象模型 ,这个模型方便于操作浏览器

浏览器对应的对象就是window对象,这个可以通过查阅DHTML API获得

  • 定义一个事件源,通过对事件源的触发,获取想要的结果
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
29
30
<body>
<script type="text/javascript" src="out.js"></script>

//定义按钮 onclick事件的处理方式
<script type="text/javascript">
//定义一函数
function windowObjDemo(){

//想要知道这个浏览器的信息。 就需要使用window对象中的navigator
var name = navigator.appName;
var version = navigator.appVersion;
println(name+":"+version);
}

//演示location
function windowObjDemo2(){

var pro = location.protocol;
var text = location.href;
alert(text);

//给location的href属性设置一个值
//改变了地址栏的值,并对其值进行了解析如果是http,还进行连接访问
location.href = "https://orangetop.github.io";
}
</script>

<!--定义事件源,注册事件关联的动作-->
<input type="button" value="演示window中的对象" onclick="windowObjDemo2()" />
</body>

window对象

  • 演示window中的常见方法
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<body>
<script type="text/javascript" src="out.js"></script>
<script type="text/javascript">
var timeid;
function windowMethodDemo(){

var b = confirm("你真的确定要点击吗?");
alert("b="+b);
//延迟4秒,弹窗
setTimeout("alert('time out run')",4000);
//每隔3秒弹窗
timeid = setInterval("alert('interval run')",3000);
}

function stopTime(){
//取消之前设置的间隔事件
clearInterval(timeid);
}


function windowMove(){

// moveBy(10,10);
// moveTo(40,40);
for (var x = 0; x < 700; x++){
//窗口抖动
moveBy(20, 0);
moveBy(0, 20);
moveBy(-20,0);
moveBy(0,-20);
}
}

function windowOpen(){
//可以作为广告,会弹出 ad.html
open("ad.html","_blank","height=400,width=400,status=no,toolbar=no,menubar=no,location=no");
c8lose();
}
</script>


<input type="button" value="演示window对象的方法" onclick="windowOpen()"/>
<input type="button" value="停止" onclick="stopTime()"/>
</body>
  • window常见事项
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<script type="text/javascript">

onunload = function(){
//在对象被卸载前触发
alert("onunload run");
}

onload = function(){
//浏览器完成对象装载后触发
alert("onload run");
}

onbeforeunload = function(){
//在对象将要被卸载前触发
alert("onbeforeunload run");
}

onload = function(){

window.status = "啊!,加载完毕啦";
}
</script>

DOM

document对象

该对象将标记型文档进行封装,作用是可以对标记型文档进行操作

若是想要实现动态效果,就需要对节点操作,那么要先获取到这个节点

要想获取节点,必须要先获取到节点所属的文档对象document

  • document对象最常见的操作就是获取页面中的节点

获取节点的方法体现:

  • 1、getElementById():
    • 通过标签的id属性值获取该标签节点,返回该标签节点
  • 2、getElementsByName():
    • 通过标签的name属性获取节点,因为name有相同,所以返回的一个数组
  • 3、getElementsByTagName():
    • 通过标签名获取节点。因为标签名会重复,所以返回的是一个数组
  • 凡是带s返回的都是数组

获取节点

  • 节点都有三个必备的属性:
    • 节点名称,节点类型,节点值
  • 常见节点有三种:
    • 1、标签型节点:类型 1
    • 2、属性节点: 类型 2
    • 3、文本节点: 类型 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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<body>
<script type="text/javascript">
function getNodeDemo(){

var divNode = document.getElementById("divid");
//获取div节点中的文本。
var text = divNode.innerHTML;
alert(text);
//改变div中的文本。
divNode.innerHTML = "文本被改了".fontcolor("red");
}

//获取文本框节点演示getElementsByName方法
function getNodeDemo2(){

var userNode = document.getElementsByName("user")[0];
alert(userNode.value);
}


//获取超链接节点对象。演示getElementsByTagName方法。
function getNodeDemo3(){

//直接用标签名获取。
var nodes = document.getElementsByTagName("a");
for(var x=0; x<nodes.length; x++){
//新窗口打开
nodes[x].target = "_blank";
}
}

</script>

<input type="button" value="演示document对象获取节点" onclick="getNodeDemo4()" />
<div id="divid">这是一个div区域</div>
<input type="text" name="user" />
<a href="http://www.sina.com.cn">网站1</a>
<a href="http://www.SOHU.com.cn">网站2</a>
<div id="newslink">
<a href="http://www.163.com.cn">新闻链接1</a>
<a href="http://www.164.com.cn">新闻链接2</a>
<a href="http://www.itcast.com.cn">新闻链接3</a>
</div>
</body>
  • 对于页面中的超链接,新闻链接通过新窗口打开,门户网站链接在当前页面打开
  • 要获取其中被操作的超链接对象,可是通过document获取超链接,拿到的是页面中所有的超链接节点。
  • 只想获取一部分该如何办呢?
  • 只要获取到被操作的超链接所属的节点即可,再通过这个节点获取到它里面所有的超链接节点
1
2
3
4
5
6
7
8
9
10
11
12
function getNodeDemo4(){

//获取超链接所属的div节点
var divNode = document.getElementById("newslink");

//通过对div对象方法的查找发现它也具备getElementsByTagName方法。
//记住:所有的容器型标签都具备这个方法。在该标签范围内获取指定名称的标签。
var aNodes = divNode.getElementsByTagName("a");
for(var x=0;x<aNodes.length; x++){
aNodes[x].target = "_blank";
}
}

节点层次

  • 通过节点的层次关系获取节点对象
  • 关系:
    • 1、父节点: parentNode:对应一个节点对象
    • 2、子节点:childNodes:对应一个节点集合
    • 3、兄弟节点:
      • 上一个兄弟节点:previousSibling
      • 下一个兄弟节点:nextSibling
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<html>
<body>
<script type="text/javascript">
function getNodeByLevel(){
//获取页面中的表格节点。
var tabNode = document.getElementById("tabid");

//获取父节点 parentNode
var node = tabNode.parentNode;
alert(node.nodeName);//body

//获取子节点 childNodes
var nodes = tabNode.childNodes;
alert(nodes[0].childNodes[0].nodeName);

//获取兄弟节点
//上一个
var node = tabNode.previousSibling;
alert(node.nodeName);

var node = tabNode.nextSibling.nextSibling;
alert(node.nodeName);


//尽量少用兄弟节点,因为在解析的时候会出现浏览器不同解析不一致,
//会解析出标签间的空白文本节点
}
</script>

<input type="button" value="通过节点层次关系获取节点" onclick="getNodeByLevel()" />

<div>div区域</div>
<span>span区域</span>
<table id="tabid">
<tr>
<td>单元格一</td>
<td>单元格二</td>
</tr>
</table>
<span>span区域11</span>
<dl>
<dt>上层项目</dt>
<dd>下层项目</dd>
</dl>
<a href=''>一个超链接</a>
</body>
</html>

创建添加节点

  • 需求:在div_1中添加节点
  • 有两种方法:
  • 第一种:
    • 创建节点,使用document中的createTextNode方法
    • 通过getElementById方法,获取div_1节点
    • 将文本节点添加到div_1节点中
  • 第二种:
    • 使用了容器型标签中的一个属性,innerHTML
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<title>Untitled Document</title>
<style type="text/css">
div{
border:#00ccff 1px solid;
width:200px;
padding:30px;
margin:10px;
}
#div_1{
background-color:#00ccff;
}
#div_2{
background-color:#FFccff;
}
#div_3{
background-color:#cc00ff;
}
#div_4{
background-color:#00FF00;
}
</style>
</head>
<body>
<script type="text/javascript">
//创建并添加节点。
//需求:在div_1节点中添加一个文本节点。
function crtAndAdd(){

//1, 创建节点。使用document中的createTextNode方法。
var oTextNode = document.createTextNode("这是一个新的文本 ");

//2,获取div_1节点。
var oDivNode = document.getElementById("div_1");

//3,将文本节点添加到div_1节点中。
oDivNode.appendChild(oTextNode);

}

//需求:在div_1中创建并添加一个按钮节点。
function crtAndAdd2(){
//1,创建一个按钮节点。
var oButNode = document.createElement("input");
oButNode.type = "button";
oButNode.value = "一个新按钮";

//2,获取div_1节点。
var oDivNode = document.getElementById("div_1");

//3,将按钮节点添加到div_1节点中。
oDivNode.appendChild(oButNode);
}

//通过另一种方式完成添加节点。
function crtAndAdd3(){

//1,获取div_1节点。
var oDivNode = document.getElementById("div_1");

//oDivNode.innerHTML = "<input type='button' value='有个按钮'/>";
oDivNode.innerHTML = "<a href='http://www.163.com'>有个超链接</a>";
}

</script>
<input type="button" value="创建并添加节点" onclick="crtAndAdd3()"/>
<input type="button" value="删除节点" onclick="delNode()"/>
<input type="button" value="修改节点" onclick="updateNode()"/>
<input type="button" value="克隆节点" onclick="cloneDemo()"/>
<hr/>

<div id="div_1">

</div>

<div id="div_2">
加油,年薪百万在招手!
</div>

<div id="div_3">
div区域演示文字
</div>

<div id="div_4">
节点的增删改查
</div>

</body>
</html>

删除节点

  • 一般用removeChild,获取父节点,删除父的子节点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//需求将div_2节点删除。 
function delNode(){

//1,获取div_2节点。
var oDivNode = document.getElementById("div_2");

//2,使用div节点的remvoeNode方法删除
//false 自杀,true 诛九族 //建议试一下false,true看看区别
//oDivNode.removeNode(true);较少用

//一般使用removeChild方法。 删除子节点。
//获取div_2的父节点,然后在用父节点的removeChild,将div_2删除。
oDivNode.parentNode.removeChild(oDivNode);

}

替换克隆节点

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
29
30
31
32
//需求:用div_3节点替换div_1节点。

function updateNode(){

//获取div-3和div-1.
//使用replaceNode进行替换。

var oDivNode_1 = document.getElementById("div_1");
var oDivNode_3 = document.getElementById("div_3");

//oDivNode_1.replaceNode(oDivNode_3);
// 建议使用replaceChild方法。

oDivNode_1.parentNode.replaceChild(oDivNode_3,oDivNode_1);

}


//需求:希望用div_3替换div-1,并保留div-3节点。
//其实就是对div_3进行克隆

function cloneDemo(){
var oDivNode_1 = document.getElementById("div_1");
var oDivNode_3 = document.getElementById("div_3");
//true 全部克隆,false 自己克隆
var oCopyDiv_3 = oDivNode_3.cloneNode(true);

//oDivNode_1.replaceNode(oDivNode_3);
// 建议使用replaceChild方法。

oDivNode_1.parentNode.replaceChild(oCopyDiv_3,oDivNode_1);
}

练习

新闻字体(大中小)

需求:新闻字体的大中小样式改变

思路:

  • 1、先有新闻数据,并用标签封装。
  • 2、定义一些页面样式。静态的样式和预定义的样式(用于动态效果,方便于事件处理时的样式加载。)
  • 3、确定事件源和事件,以及处理方式中被处理的节点。
    • 事件源:a标签,事件:onclick,被处理的节点:div-newstext
  • 4、用 Js处理页面的行为

    然要给超链接加入自定义的事件处理,就要先取消超链接的默认点击效果

可以使用给 href 设置:javascript:void(0) 来完成

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GBK">
<title>Untitled Document</title>

<style type="text/css">
/*超链接访问前,访问后样式一致*/
a:link,a:visited{
color:#0044ff;
text-decoration:none;
}
a:hover{
color:#ff8800;
}
#newstext{

width:500px;
border:#00ff00 1px solid;
padding:10px;
}
</style>
</head>
<body>
<script type="text/javascript">
//定义 改变字体 的方法。
function changeFont2(size,clr){

//既然要对div newstext中的文本字体进行操作。
//必须要先获取div节点对象。
var oNewsText = document.getElementById("newstext");

//获取oNewText节点的style样式属性对象。
oNewsText.style.fontSize = size;
oNewsText.style.color = clr;
}

</script>

<h1>这是一个新闻标题</h1>
<hr/>
<a href="javascript:void(0)" onclick="changeFont('max')">大字体</a>
<a href="javascript:void(0)" onclick="changeFont('norm')">中字体</a>
<a href="javascript:void(0)" onclick="changeFont('min')">小字体</a>
<div id="newstext" class="norm">
6月21日,夏至,太阳光将直射北回归线,北半球的白昼也达到了全年最长。
对于北纬40°左右地区,夏至前后几天夜晚可观星的时间只有短短不到5个小
时。即便如此,六月的夜空依然很精彩,土星将在本月迎来冲日,还有几个流
星雨活动,但它们的流量都不大。
</div>
</body>
</html>
  • 如果根据用户点击所需要的效果不唯一,仅通过传递多个参数虽然可以实现效果
  • 但是存在很多缺点
    • 传参过多,阅读性差
    • Js 代码和 CSS代码耦合性高
    • 不利于扩展
  • 解决办法:
    • 将多个所需的样式进行封装
    • 封装到选择器中,只要给指定的标签加载不同的而选择器就可以了
1
2
3
4
function changeFont(selectorName){
var oNewsText = document.getElementById("newstext");
oNewsText.className = selectorName;
}

全选文本框

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<html lang="en">
<head>
<meta charset="UTF-8">
<title>全选</title>
<script>
function checkAll(){
//1.获取编号前面的复选框
var checkAllEle = document.getElementById("checkAll");
//2.对编号前面复选框的状态进行判断
if(checkAllEle.checked==true){
//3.获取下面所有的复选框
var checkOnes = document.getElementsByName("checkOne");
//4.对获取的所有复选框进行遍历
for(var i=0;i<checkOnes.length;i++){
//5.拿到每一个复选框,并将其状态置为选中
checkOnes[i].checked=true;
}
}else{
//6.获取下面所有的复选框
var checkOnes = document.getElementsByName("checkOne");
//7.对获取的所有复选框进行遍历
for(var i=0;i<checkOnes.length;i++){
//8.拿到每一个复选框,并将其状态置为未选中
checkOnes[i].checked=false;
}
}
}
</script>
</head>
<body>
<table border="1" width="500" height="50" align="center" >
<thead>
<tr>
<td colspan="4">
<input type="button" value="添加" />
<input type="button" value="删除" />
</td>
</tr>
<tr>
<th><input align="" type="checkbox" onclick="checkAll()" id="checkAll"/>全选</th>
<th>编号</th>
<th>姓名</th>
<th>年龄</th>
</tr>
</thead>
<tbody>
<tr >
<td><input type="checkbox" name="checkOne"/></td>
<td>1</td>
<td>张三</td>
<td>22</td>
</tr>
<tr >
<td><input type="checkbox" name="checkOne"/></td>
<td>2</td>
<td>李四</td>
<td>25</td>
</tr>
</tbody>
</table>
</body>
</html>

省市二级联动

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<html lang="en">
<head>
<meta charset="UTF-8">
<title>二级联动</title>
<style>

</style>
<script>
var cities = new Array(3);
cities[0] = new Array("武汉市","黄冈市","襄阳市","荆州市");
cities[1] = new Array("长沙市","郴州市","株洲市","岳阳市");
cities[2] = new Array("石家庄市","邯郸市","廊坊市","保定市");
cities[3] = new Array("郑州市","洛阳市","开封市","安阳市");

function changeCity(val) {
//1、获取第二个下拉列表
var cityEle = document.getElementById("city");
//2、清空第二个下拉列表的option内容
cityEle.options.length = 0;
//3、遍历二维数组中的省份
for(var i=0;i<cities.length;i++){
//注意,比较的是角标
if(val==i){
//4、遍历用户选择的省份下的城市
for(var j=0;j<cities[i].length;j++){
//alert(cities[i][j]);
//5、创建城市的文本节点
var textNode = document.createTextNode(cities[i][j]);
//6、创建option元素节点
var opEle = document.createElement("option");
//7、将城市的文本节点添加到option元素节点
opEle.appendChild(textNode);
//8、将option元素节点添加到第二个下拉列表中去
cityEle.appendChild(opEle);
}
}
}
}
</script>
</head>
<body>
<div>
<table border="1" align="center" height="70%" bgcolor="white">
<tr>
<td colspan="2" align="center">
<font size="5">会员注册</font>
</td>
</tr>
<tr>
<td>籍贯</td>
<td>
<select onchange="changeCity(this.value)">
<option>--请选择--</option>
<option value="0">湖北</option>
<option value="1">湖南</option>
<option value="2">河北</option>
<option value="3">河南</option>
</select>
<select id="city">

</select>
</td>
</tr>
</table>
</div>
</body>
</html>