DOM模型

一、DOM模型概述 HTML文档只有一个根节点,而其他节点以根节点子节点或孙子节点的形式存在。最终形成一个结构化文档。DOM模型则用于导航、访问结构化文档的节点,并提供新增,修改,删除结构化本档的能力。 DOM并不是一种技术,它只是访问结构化文档(主要是XML文档和HTML文档)的一种思想。DOM解析器的作用就是完成结构化文档和DOM树之间的转换关系。通常来说,DOM解析器解析结构化文档就是将磁盘上的结构化文档转换成内存中的DOM树,而从DOM树输出结构化文档就是将内存中的DOM树转换成磁盘上的结构化文档。
如图:
DOM模型
文章图片

二、DOM模型和HTML文档 1、HTML元素之间的继承关系
DOM为常用的HTML元素提供了一套完整的继承体系。从页面的document对象到每个常用的HTML元素DOM模型都提供了对应的类,每个类都提供了相应的方法来操作DOM元素本身属性及其子元素,DOM模型允许以树的方式操作HTML文档中的每个元素。
DOM模型里的HTML元素的继承关系:
DOM模型
文章图片

在图14.3中,粗线框框出的4个元素:Node、Document、Element、HTMLElement都是普通HTML元素的超类,不直接对应于HTML页面控件,但它们所包含的方法也可其他页面元素调用。除此之外,还有如下常用的HTMl元素:
DOM模型
文章图片

2、HTML元素之间常见的包含关系
有些HTML元素之间可以相互嵌套,例如元素可以相互嵌套,但有些HTML元素则不可互相嵌套,例如元素只能作为元素的子元素,元素只能作为元素的子元素。
下图描述了常用HTML元素之间的包含关系:
DOM模型
文章图片

如图可以看出,HTMLDocument对象作为整个HTML文档的最大对象,里面可以包含一个HTMLBodyDocument对象。HTML文档中还有两个对象体系:表单对象和表格对象。

  • 表单对象里可以包含基本的输入对象,还可以包含元素元素可以包含多个元素。
  • 表格对象可以包含标题(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属性值。
    例:
Document - 锐客网 ="text/javascript"> var accessById = function() { alert (document.getElementById("a").innerHTML + "\n" + document.getElementById("b").value); }
示例

点击按钮前后:
DOM模型
文章图片

DOM模型
文章图片

可能有读者感到奇怪,程序中为了访问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选择器即可。
例:
Document - 锐客网 ="text/javascript"> var accessById = function() { alert (document.querySelector("#a").innerHTML + "\n" + document.querySelector("#b").value); }
阿斯蒂芬

(与前一个示例基本相同)
下面示范了querySelectorALL()方法同时获取多个HTML元素的情形:
Document - 锐客网 ="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"; } }

结果(单击按钮):
DOM模型
文章图片

3、利用节点关系访问HTML元素
一旦获取了某个HTML元素,由于该元素实际上与DOM树的某个节点对应,因此可以利用节点之间的父子、兄弟关系来访问HTML元素。
利用节点关系访问HTML元素的属性和方法如下:
DOM模型
文章图片

例:
Document - 锐客网 ="text/css"> .selected{ background-color: #66f; }
  1. 嘉大厦速度
  2. 发达水电费
  3. 法规及
  4. 速度十多个
  5. 森岛帆高
  6. 阿瑟阿萨德
="text/javascript"> var curTarget = document.getElementById("ajax"); var change = function(target) { alert(target.innerHTML); }

结果(单击’第一个’按钮):
DOM模型
文章图片

这其中可能有读者感到疑惑。用了两次previousSibling属性,这不是访问上两个兄弟节点吗?没有错,其实就是访问上两个节点。因为ol节点一共包含13个子节点,而不是六个子节点,因为在每两个之间都有一片空白,这个空白也算一个子节点。
4、访问表达控件
表单在DOM中有HTMLFromElement对象表示,该对象除了可调用前面介绍的基本属性和方法之外,还有如下几个常用的属性。
DOM模型
文章图片

HTMLFormElement访问表单控件有如下三种语法:
DOM模型
文章图片

5、访问列表框、下拉菜单的选项
HTMLSelectElement代表一个列表框或下拉菜单,HTMLSelectElement对象除了可使用普通HTML元素的各种属性和方法外,还支持如下额外的属性。
DOM模型
文章图片

HTMLSelectElement的options属性可直接访问列表框下拉菜单的所有列表项。传入指定索引器可访问指定列表项,语法格式如下。
DOM模型
文章图片

下面的页面代码示范了访问列表框、下拉菜单中列表项的用法:
Document - 锐客网 ="mySelect" id="mySelect" size="6">
="text/javascript"> var curTarget = document.getElementById("mySelect"); var change = function(target) { alert(target.text); }

DOM模型
文章图片

6、访问表格子元素
HTMLTableElement代表表格,HTMLTableElement对象除了可使用普通HTML元素的各种属性和方法外。还支持如下额外的属性。
DOM模型
文章图片

在获得一个表格之后,可以通过上面提供的一系列属性来访问表格“内容”,例如caption属性返回该表格标题。rows属性返回该表格的全部表格行。
如果需要访问表格的指定表格行时,只需要如下格式。
DOM模型
文章图片

HTMLTableCellElement代表单元格,HTMLTableCellElement对象除了可使用普通HTML元素的各种属性和方法外,还支持如下额外属性。
cellIndex :返回该单元格在该表格行内的索引值只读属性。
下面的代码示范了如何访问HTML表格的内容。
Document - 锐客网
阿斯蒂芬
江特电机 安抚安抚
sdfadf hhfdh
asdfs tktyu

结果:
DOM模型
文章图片

四、修改HTML元素 访问到指定HTML元素之后,还可以对该元素进行修改。通过修改HTML元素,就可以实现动态更新HTML元素页面的目的了。
修改节点通常是修改节点的内容,修改节点的属性或者修改节点的CSS样式。总结起来一句话,HTML元素的所有读写属性都可以被修改,一旦HTML元素的属性值被修改,HTML页面上对应的内容也就随之改变。改变HTML元素通常通过修改如下几个常用属性来实现。
DOM模型
文章图片

下面示例代码演示一个可编辑的表格,在页面中指定需要修改的表格行列,然后输入要修改的值,就可以动态地修改单元格的内容。
Document - 锐客网 改变第行, 第列的值为:
江特电机 安抚安抚
sdfadf hhfdh
asdfs tktyu
="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("d"); var cel = document.getElementById("cel").value; cel = parseInt(cel); if(isNaN(cel)) { alert("您要修改的列必须是整数"); return false; } if (row > tb.rows.length || cel > tb.rows.item(row-1).cells.length) { alert("要修改的单元格不再该表格内"); return false; } if(document.getElementById("celVal").value != "") tb.rows.item(row - 1).cells.item(cel - 1).innerHTML = document.getElementById("celVal").value; }

结果:
DOM模型
文章图片

五、增加HTML元素 JavaScript脚本可以为DOM动态增加节点,程序为DOM树增加节点时,页面会动态的增加HTML元素。当需要为页面增加HTML元素时。应按如下两个步骤操作。
  1. 创建或复制节点。
  2. 添加节点。
1、创建或复制节点
创造节点通常借助于document对象的createElement方法来实现语法如下。document.createElemen(Tag):创建Tag标签对应的节点。
当调用document.createElemen(“div”)创建节点后,将自动生成一个HTMLDivElement对象,该对象对应于HTML文档中的div元素。因此在创建元素时,传入的参数字符串并不是随意填写的,必须是一个合法的标签名。
创建一个节点的开销可能过大,实际上还可以复制一个已有的节点。复制已有的节点对系统开销略小。通过调用Node的cloneNode()的方法即可复制一个已有的节点。该方法的语法格式如下。
Node cloneNode(boolean deep):复制当前节点。当deep为true时,表示在复制当前节点的同时复制该节点的全部后代节点。当deep为false时,表示仅复制当前节点。
例:
Document - 锐客网
  • 123
="text/javascript"> var ul = document.getElementById("d"); var ajax = ul.firstChild.nextSibling.cloneNode(false); ajax.innerHTML = "456"; ul.appendChild(ajax);

结果:
DOM模型
文章图片

2、添加节点
当一个节点创建成功后,一定要将该节点添加到DOM树中才能显示出来,对于普通的节点,可采用Node对象的如下方法来添加节点。
DOM模型
文章图片

还可以一次性增加多个节点。
例:
Document - 锐客网 ="text/javascript"> var a = document.createElement("select"); for (var i = 0 ; i< 10 ; i++) { varop = document.createElement("option"); op.innerHTML = '新增的选项' + i; a.add(op,null); } a.size = 5; document.getElementById("test").appendChild(a);

结果:
DOM模型
文章图片

3、为列表框、下拉菜单添加选项
为列表框下拉菜单添加子节点,也就是为列表框下拉菜单添加选项添加选项有两种方法。
  • 直接调用HTMLSelectElement的add()方法添加选项。
  • 直接为select的指定选项赋值。
HTMLSelectElement包含如下方法用于添加新选项。
DOM模型
文章图片

下列代码示范了通过这种方式来添加选项。
Document - 锐客网 ="text/javascript"> var a = document.createElement("select"); for (var i = 0 ; i< 10 ; i++) { varop = document.createElement("option"); op.innerHTML = '新增的选项' + i; a.add(op,null); } a.size = 5; document.getElementById("test").appendChild(a);

结果:
DOM模型
文章图片

上面的页面程序在早期的IE浏览器。(如IE8及以前版本)中将出现错误,主要是因为它不允许调用add()方法时指定最后一个参数为null。为了避免这种情况,可使用直接为指定选择指定选项赋值的方法来添加选项。
为指定选项赋值所支持的值必须是一个有效的选项,创建选项除了可使用前面所示的createElement方法之外,还可以使用如下构造器。
new Option(text,value,defaultSelected,selected)

该构造器有四个参数,这四个参数说明如下。
  • text:该选项的文本即该选项所呈现的“内容”。
  • value:选中该选项的值。
  • defaultSelected:设置默认是否选中该选项。
  • selected:设置该选项当前是否被选中。
并不是每次构造该选项都需要指定4个参数,也可以只指定一个参数或者两个参数。如果构造Option对象时,只指定了一个参数,则该参数是Option的text值,如果指定了两个参数,则第一个参数是text,第二个参数是value。
例:
Document - 锐客网 ="text/javascript"> var a = document.createElement("select"); a.style.width = "200px"; for (var i = 0 ; i < 10 ; i++) { var op = new Option('新增的选项' + i,i); a.options[i] = op; } a.size = 5; document.getElementById("test").appendChild(a);

结果:
DOM模型
文章图片

4、动态添加表格内容
表格元素、表格行则另有添加子元素的方法,实际上他们可以在添加子元素的同时创建这些子元素。也就是说,添加表格子元素时,往往无需使用document的createElement方法来创建节点。
HTMLTableElement对象有如下方法。
DOM模型
文章图片

下面通过脚本在页面中动态生成一个表格。
Document - 锐客网 ="text/javascript"> var a = document.createElement("table"); a.style.width = "800px"; a.style.borderCollapse = "collapse"; a.border=1; var caption = a.createCaption(); caption.innerHTML = "表格标题"; for (var i = 0; i<5; i++) { var tr = a.insertRow(i); for (var j= 0; j<7; j++) { var td = tr.insertCell(j); td.style.padding = "5px"; td.innerHTML = "单元格内容" + i+j; } } document.getElementById("test").appendChild(a);

结果:
DOM模型
文章图片

自己输入增加表格:
Document - 锐客网 添加行 添加列 标题:
="text/javascript"> var change = function() { 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; }var a = document.createElement("table"); a.style.width = "800px"; a.style.borderCollapse = "collapse"; a.border=1; var caption = a.createCaption(); caption.innerHTML = document.getElementById("celVal").value ; for (var i = 0; i

结果:
DOM模型
文章图片

六、删除HTML元素 删除HTML元素也是通过删除节点来完成的。对于普通的HTML元素,可用通用方法来删除节点,而列表框、下拉菜单列表则有额外的方法来删除HTML元素。
1、删除节点
删除节点通常借助于其父节点,Node对象提供了如下方法来删除子节点。
removeChild(oldNode):删除oldNode子节点。
在从父节点中删除该子节点后,该子节点代表的内容也会消失。
2、删除列表框、下拉菜单的选项
删除列表框、下拉菜单的选项有两种方法:
  • 利用HTMLSelectElement对象的remove()方法删除选项。
  • 直接将指定选项赋为null即可。
对于HTMLSelectElement对象而言,它提供了如下方法用于删除选项。
  • remove(long index):删除指定索引处的选项。
上面方法中的index是需要删除选项所在的索引值,如果该索引值比下拉列表中选项的最大索引值还大,或者索引值小于零,则该方法不会删除任何选项。
下面的页面演示了动态增加下拉列表的选项,并可以删除下拉列表的选项。
Document - 锐客网
="show" size="8" style="width: 180px; "> ="text/javascript"> var show = document.getElementById("show"); var add = function() { var op = new Option(document .getElementById('opValue').value); show.options[show.options.length] = op; } var del = function() { if(show.options.length > 0) { show.remove(show.options.length -1); } }

结果:
DOM模型
文章图片

(在文本框中输入一个值,单击添加按钮就可以将其添加到下拉列表中,如果单击删除按钮。则将删除最新增加的一个选项。)
3、删除表格的行或单元格
删除表格的指定表格行使用HTMLTableElement对象的如下方法。
  • deleteRow(long index):删除表格中index索引处的行。
删除表格行的指定单元格使用HTMLRowElement对象的如下方法。
  • deleteCell(long index):删除某行index索引处的单元格。
下面的代码可以动态删除页面中的表格行,也可以动态删除表格中的单元格。
Document - 锐客网

删除第行, 第
市房管局来看
江特电机 安抚安抚
sdfadf hhfdh
asdfs tktyu
="text/javascript">var tab = document.getElementById("test"); var delrow = function() { if (tab.rows.length > 0) { tab.deleteRow(tab.rows.length - 1); }} var delcell = function() { var rowList = tab.rows; var lastRow = rowList.item(rowList.length -1); if(lastRow.cells.length > 0) { lastRow.deleteCell(lastRow.cells.length -1); } if(lastRow.cells.length==0){ delrow(); } } var change = function() { var tb = document.getElementById("test"); 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(row-1).cells.length) { alert("要修改的单元格不再该表格内"); return false; } tb.rows[row-1].deleteCell(cel-1); }

【DOM模型】结果(删除最后一行的最后一格,也可以指定第几行第几列):
DOM模型
文章图片

    推荐阅读