一、DOM模型概述
在了解JS的DOM模型之前,首先要先清除什么是树模型,这一点在数据结构中讲述的非常清楚,不知道的读者可以先去看一下数据结构中有关树的概念。
了解了什么是树之后,我们再来说说DOM模型,DOM模型其实就是把你所有已经写入前端文件(.html/.jsp/..)中的所有标签,形成一个树的结构。话不多说,直接上代码和图。
<html>
<head><title>我的DOM树</title></head>
<body>
<h1>My name is BeryAllen,</h1>
<h2>and I'm the fastest man alive.</h2>
</body>
</html>
如上的代码会生成一个DOM树,其中html为树的根节点,<head/>和<body/>为它的两个子节点,而<body/>下还会有<h1/>和<h2/>两个子节点,该树形结构如下图所示:
DOM为常用的HTML元素提供了一套完整的继承体系。从页面的document对象到每个常用的HTML元素,DOM模型都提供了对应的类,每个类都提供了相应的方法来操作DOM元素本身、属性及其子元素。DOM模型允许以树的方式操作HTML文档中的每个元素。
虽然JS不是一门纯粹的面向对象语言,但DOM还是为HTML元素提供了一种简单的继承关系。关于HTML中元素的继承关系,具体的可以查看以下链接:https://blog.csdn.net/ppwwp/article/details/88169145。
二、访问HTML元素
为了动态地修改HTML元素,必须能访问HTML元素,DOM提供了三种方式来访问HTML元素:
- 根据ID访问HTML元素
- 利用节点关系访问HTML元素
前一种方式通过document.getElementById("")可以通元素的ID获取该对象,与之类似的,也可以通过class获得元素对象,如:document.getElementsByClassName("");后一种方式可以通过节点之间的父子、兄弟关系来访问。
除了这两种访问方式之外,还可以通过CSS选择器来访问HTML元素。
<head>
<script type="text/javascript">
var accessById = function(){
alert(document.querySelector("#a").innerHTML + "\n"
+ document.querySelector("#b").value);
}
</script>
</head>
<body>
<div id="a">疯狂Java讲义</div>
<textarea id="b" row="3" cols='25'>轻量级Java EE企业应用到实战</textarea>
<input type="button" value="访问2个元素" onclick="accessById()"/>
</body>
通过父子节点获取元素:
<head>
<style type="text/css">
.selected{
background-color:#66f;
}
</style>
</head>
<body>
<ol id="books">
<!-- 第一个子节点:空白 -->
<li id="java">疯狂Java讲义</li>
<!-- 第二个子节点是java,第三个子节点是:空白 -->
<li id="ssh">轻量级Java EE企业应用到实战</li>
<li id="ajax" class="selected">疯狂Ajax讲义</li>
<li id="xml">疯狂XML讲义</li>
<li id="ejb">经典Java EE企业应用到实战</li>
<li id="android">经典Java EE企业应用到实战</li>
</ol>
<input type="button" value="父节点"
onclick="change(curTarget.parentNode);"/>
<input type="button" value="第一个"
onclick="change(curTarget.parentNode.firstChild.nextSibling);"/>
<input type="button" value="上一个"
onclick="change(curTarget.parentNode.previousSibling);"/>
<input type="button" value="下一个"
onclick="change(curTarget.nextSibling.nextSibling);"/>
<input type="button" value="最后一个"
onclick="change(curTarget.parentNode.lastChild.previousSibling);"/>
<script type="text/javascript">
var curTarget = document.getElementById("ajax");
var change = function(target){
alert(target.innerHTML);
}
</script>
</body>
三、修改HTML元素
访问到指定的HTML元素之后,还可以对该元素进行修改,可以通过以下属性进行修改:
- innerHTML:大部分HTML页面元素如<div/>、<td/>的呈现内容由该属性控制。
- value:表单控件如<input/>、<textarea/>的呈现内容由该属性控制
- className:修改HTML元素的CSS样式,该属性的合法值是一个class选择器名
- style:修改HTML元素的CSS样式
- options[index]:直接对<select/>元素的指定列表项赋值,可改变列表框、下拉菜单的指定列表项。
<head>
<title>BeryAllen</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<style type="text/css">
</style>
</head>
<body>
改变第<input id="row" type="text" size="2"/>行,
第<input id="cel" type="text" size="2" />列的值为:
<input id="celVal" type="text" size="16"/>
<input id="chg" type="button" value="改变" onclick="change();"/><br />
<table id="d" border="1" style="width:580px;border-collapse:collapse;">
<tr>
<td>疯狂Java讲义</td>
<td>轻量级Java EE企业应用到实战</td>
</tr>
<tr>
<td>疯狂Ajax讲义</td>
<td>轻量级Java EE企业应用到实战</td>
</tr>
<tr>
<td>疯狂XML讲义</td>
<td>疯狂Android讲义</td>
</tr>
</table>
<script type="text/javascript">
var change = function(){
var tb = document.getElementById("d");
var row = document.getElementById("row").value;
row = parseInt(row);
if(isNaN(row)){
alert("您要修改的行必须是整数");
return false;
}
var cel = document.getElementById("cel").value;
cel = parseInt(cel);
if(isNaN(cel)){
alert("您要修改的列必须是整数");
return false;
}
if(row > tb.rows.length ||
cel > tb.rows.item(0).cells.length){
alert("要修改的单元格不在该表格内");
return false;
}
tb.rows.item(row - 1).cells.item(cel - 1).innerHTML
= document.getElementById("celVal").value;
}
</script>
</body>
如上的代码在获取了table对象d后,通过tb.rows.item(row - 1 ).cells.item(cel - 1).innerHTML
= document.getElementById("celVal").value;将输入的第row行,cel列的数据变为input框中的数据。
四、增加HTML元素
JavaScript脚本可以通过DOM动态增加节点,程序为DOM树增加节点时,页面会动态的地增加HTML元素。当需要为页面增加HTML元素时,可以进行如下的操作:
1、创建或复制节点
2、添加节点
<body id="test">
<script type="text/javascript">
var a = document.createElement("select");
for(var i = 0;i<10;i++){
var op = document.createElement("option");
op.innerHTML = '新增的选项' + i;
a.add(op,null);
a.size = 5;
document.getElementById("test").appendChild(a);
}
</script>
</body>
从运行结果可以看出,该自选框以及框内的内容都是由JavaScript动态生成的,不需要静态的定义。
javascript这样动态生成的特点,可以减少JS对HTML的依赖性,这样极大的增加了代码的可重用性。
五、删除HTML元素
删除HTML元素也是通过删除节点来完成的。对于普通的HTML元素,可以通过方法来删除节点,而列表框、下拉菜单、表格则有额外的方法来删除HTML元素。
<body id="test">
<input id="add" type="button" value="增加" disabled onclick="add();"/>
<input id="del" type="button" value="删除" onclick="del();"/>
<div id="target" style="width:240px;height:50px;border:1px solid black;"></div>
<script type="text/javascript">
var body = document.getElementById("test");
var target = document.getElementById("target");
var add = function(){
body.appendChild(target);
document.getElementById("add").disabled = "disabled";
document.getElementById("del").disabled = "";
}
var del = function(){
body.removeChild(target);
document.getElementById("del").disabled = "disabled";
document.getElementById("add").disabled = "";
}
</script>
</body>
通过点击删除来将id为target的div移除,点击删除之后删除按钮不可点击,增加按钮变得可以点击。
我们再来看看表格中删除某行某列的做法:
<body>
第<input type="text" id="row"/>行,第<input type="text" id="col"/>列
<input type="button" onclick="del();" value="删除第i列第j行"/><br />
<table id="test" border="1px solid black;" style="width:500px;">
<caption>疯狂Java体系</caption>
<tr>
<td>疯狂Java讲义</td>
<td>轻量级Java EE企业应用实战</td>
</tr>
<tr>
<td>疯狂Java讲义</td>
<td>轻量级Java EE企业应用实战</td>
</tr>
<tr>
<td>疯狂Java讲义</td>
<td>轻量级Java EE企业应用实战</td>
</tr>
</table>
<script type="text/javascript">
var tab = document.getElementById("test");
var del = function(){
var row = document.getElementById("row").value;
var col = document.getElementById("col").value;
var rowList = tab.rows;
if(row==""||col==""){
alert("不可为空");
}
if(isNaN(row)){
alert("行输入不规范");
return false;
}
if(isNaN(col)){
alert("列输入不规范");
return false;
}
if(row > rowList.length||row<0){
alert("不存在该行");
return false;
}
let delrow = rowList.item( row - 1);
let cols = tab.rows[row-1].cells.length;
if(col > cols || col<0){
alert("不存在该列");
return false;
}
delrow.deleteCell(col-1);
}
</script>
</body>
在表格的删除中,通过用户输入数字来指定要删除的某行某列,其中要注意的是,table.rows能够获得一个数组对象,所以索引值由0开始,故而和用户的输入之间要相差1;其次,为了规避用户的不规则输出,我通过isNaN()函数判断获得到的input框的value是否可以转为数字,借此判断用户输入的规范性;得到行和列之后还要对行和列进行数量上的判断,用户输入为负数或者输入的大于总行数或列数大于总列数,都要停止删除行为,用return false强行结束del()函数。
在对该代码进行测试的过程中,我们还能够发现有趣的事情,那就是,在把某一行完全删除后,该行不会消失,但列都已经不存在了,这个时候我们就可以通过一个判断来判定该行是否还有列元素。
if(cols==1){
//如果被删除之前只有一列,则在删除该列之后该行为空,故要删除该行
tab.deleteRow(row-1);
}
把上面的代码放在删除操作之后就可以完成你想要的效果啦。