1、单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,DOM,(,Document Object Model,,,文档对象模型)是由,W3C,制定的标准,它为应用程序访问和操作,XML,和,HTML,文档提供了一套标准的,API,。,DOM,可以分为,3,个部分:核心,DOM,接口以及针对,XML,和,HTML,的,DOM,标准接口。,JavaScript,编程中使用的是,HTML DOM,,,当然它是在核心,DOM,的基础上扩展而来的。,本章将首先介绍,DOM,标准相关的基础知识,然后介绍如何在,JavaScript,中使用,DOM,进行节点的访问和操作,最
2、后通过一系列应用示例说明,DOM,在,Web,编程中的应用。,DOM,标准,7.1,使用,DOM,7.2,DOM,应用示例,7.3,7.1 DOM,标准,DOM,是由,W3C,制定的标准,目前有,3,个不同的版本,分别称之为,DOM Level 1,3,,,但浏览器厂商并没有完全按照,DOM,标准来实现浏览器。,目前与,DOM,标准兼容最好的浏览器是,Mozilla,Filefox,,,它实现了绝大部分的,DOM Level 2,特性和少量,DOM Level 3,特性,而,Internet Explorer,在这方面落在最后,它对,DOM Level 1,的实现都还不完整,尚有很多方面有待完
3、善。,7.1.1,什么是,DOM,【,例,7-1】,ex1.html,图,7-1 Internet Explorer,中的,DOM,树结构,图,7-2 Mozilla Firefox,中的,DOM,树结构,7.1.2 DOM,标准接口,表,7-1DOM,标准特性,版,本,特,性,说,明,IE,FF,1.0,HTML,核心与,HTML,接口,XML,核心与,XML,接口,2.0,Core,核心接口,HTML,HTML,接口,XML,XML,接口,Views,基于特定样式完成对文档的格式化,StyleSheets,为文档关联样式表,CSS,CSS 1,支持,CSS2,CSS 2,支持,Events
4、通用,DOM,事件,Events,通用,DOM,事件,UIEvents,用户界面事件,MouseEvents,鼠标事件,HTMLEvents,HTML,事件,MutationEvents,DOM,树发生改变时触发的事件,Range,对,DOM,树中的特定范围进行操作,Traversal,遍历,DOM,树,Core,核心接口,XML,XML,接口,LS,在文件和,DOM,树之间同步地加载和存储,LS-,Async,在文件和,DOM,树之间异步地加载和存储,Validation,修改,DOM,之后仍保持其有效性的方法,3.0,2.0,1,DOM,核心接口,表,7-2DOM,节点类型,节,点,接,
5、口,nodeType,常量(值),含,义,Element,ELEMENT_NODE(1),Element,接口代表文档中的一个元素,元素可以带有关联的属性(,Attributes,),,对应着,HTML,文档中标签内部的内容,例如:,some text,就是,HTML,文档中的一个元素,Attr,ATTRIBUTE_NODE(2),Attr,接口代表,Element,对象的一个属性,通常在文档类型定义(,DTD,),中定义属性的允许值,Text,TEXT_NODE(3),Text,接口代表,Element,对象或者,Attr,对象中的文本内容,CDATASection,CDATA_SECTIO
6、N_NODE(4),CDATASection,接口代表,标签内部的文本块,EntityReference,ENTITY_REFERENCE_NODE(5),EntityReference,接口代表文档中的实体引用节点,例如:,&,quot,;,代表双引号的实体引用,Entity,ENTITY_NODE(6),Entity,接口代表,DTD,中的一个实体定义,ProcessingInstruction,PROCESSING_INSTRUCTION_NODE(7),ProcessingInstruction,接口代表一个处理指令,Comment,COMMENT_NODE(8),Comment,接口
7、代表文档中的一段注释,Document,DOCUMENT_NODE(9),Document,接口代表文档的顶层节点,DocumentType,DOCUMENT_TYPE_NODE(10),DocumentType,接口代表文档的,DTD,引用,使用,标签可以在文档中添加,DTD,引用,DocumentFragment,DOCUMENT_FRAGMENT_NODE(11),DocumentFragment,接口代表文档的一个片段,Notation,NOTATION_NODE(12),Notation,接口代表,DTD,中定义的标记,图,7-3,DOM Level 1,核心接口,2,DOM HTM
8、L,接口,图,7-4 DOM Level 1 HTML,接口,7.1.3 DOM,标准的使用,以上对,DOM,标准的核心对象作了简要介绍,那么在实际应用中如何判断我们使用的方法是,DOM,标准所定义的呢?,最直接的方法是查阅,DOM,的标准规范,在下面的网址可以找到,DOM Level 1,3,的所有文档:,www.w3.org/DOM/DOMTR,7.2,使用,DOM,DOM,在,HTML,页面中的应用包括以下几类:,(,1,)访问指定节点;,(,2,)访问相关节点;,(,3,)访问节点属性;,(,4,)检查节点类型;,(,5,)创建节点;,(,6,)操作节点。,7.2.1,访问指定节点,“
9、访问指定节点”的含义是已知节点的某个属性(如,id,属性、,name,属性或者节点类型),在,DOM,树中寻找符合条件的节点。,相关的方法包括,getElementById,(),,,getElementsByName,(),和,getElementsByTagName,。,1,getElementById,方法,应用,getElementById,方法可以根据传入的,id,参数返回指定的元素节点。,在,HTML,文档中,元素的,id,属性是该元素对象的唯一标识,因此,getElementById,方法是最快的节点访问方法。,例如例,7-2,所示的,HTML,页面。,【,例,7-2,】,ex2
10、html,(,HTML,部分),【,例,7-3】,ex2.html,(,完整),2,getElementsByName,方法,getElementsByName,方法将查找所有元素对象,返回,name,属性为指定值的元素对象列表。,例如例,7-4,所示的,HTML,页面。,【,例,7-4,】,ex3.html,(,HTML,部分),3,getElementsByTagName,方法,getElementsByTagName,方法将返回指定类型的元素集合,与前面介绍的,getElementById,和,getElementsByName,方法不同,,getElementsByTagName,不
11、仅可以用于,Document,对象,而且可以用于普通的,Element,对象。,考虑例,7-5,所示的,HTML,页面。,【,例,7-5,】,ex4.html,(,HTML,部分),【,例,7-6】,ex4.html,(,JavaScript,部分),7.2.2,访问元素属性,Node,接口中已经具有,attributes,方法,且已被所有类型的节点继承,但是只有,Element,节点才能拥有属性。,Element,节点的,attributes,属性是,NamedNodeMap,类型的,它提供了一些用于访问和处理其内容的方法:,(,1,),getNamedItem(name,),:返回,nod
12、eName,属性值为,name,的节点;,(,2,),removeNamedItem(name,),:删除,nodeName,属性值为,name,的节点;,(,3,),setNamedItem(node,),:将,node,添加到列表,按其,nodeName,属性进行索引;,(,4,),item(pos,),:返回,pos,位置处的节点。,但是这些方法使用时有些累赘,,DOM,又定义了,3,个元素方法来帮助访问属性:,(,1,),getAttribute(name,),:,相当于,attributes.getNamedItem(name).value,;,(,2,),setAttribute(
13、name,value),:,相当于,attributes.getNamedItem(name).value,=value,;,(,3,),removeAttribute(name,),:,相当于,attributes.removeNamedItem(name,),。,考虑在例,7-7,所示的,HTML,页面中访问元素的属性。,【,例,7-7,】,ex5.html,7.2.3,访问相关节点,“访问相关节点”的含义是根据已知的节点,寻找和它存在联系的节点,如父节点、子节点、兄弟节点等。,下面介绍在,DOM,中访问相关节点的方法。,1,documentElement,属性,通过,documentEl
14、ement,属性可以很方便地访问到,HTML,文档的根节点,即,元素。,【,例,7-8,】,ex6.html,2,ownerDocument,属性,ownerDocument,属性也是在,Node,接口中定义的,该属性返回了,DOM,节点所在的文档对象。,【,例,7-9,】,ex7.html,3,访问子节点,Node,接口定义了以下的属性,可以用于访问,DOM,节点的子节点:,(,1,),childNodes,:,子节点的列表;,(,2,),firstChild,:,第一个子节点;,(,3,),lastChild,:,最后一个子节点。,4,访问父节点,Node,接口定义了,parentNode
15、属性,可以用于访问,DOM,节点的父节点,,5,访问兄弟节点,Node,接口还定义了以下的属性,用于访问,DOM,节点的兄弟节点:,(,1,),previousSibling,:,上一个兄弟节点;,(,2,),nextSibling,:,下一个兄弟节点。,7.2.4,检查节点类型,在,DOM,中可以使用节点的,nodeType,和,nodeName,属性检查节点的类型,表,7-3,所示为各类,DOM,节点的,nodeType,和,nodeName,属性值。,表,7-3DOM,节点的,nodeType,和,nodeName,接,口,nodeType,nodeName,Element,1,元素标
16、签名称,Attr,2,属性名称,Text,3,#text,CDATASection,4,#,cdata,-section,EntityReference,5,实体引用名称,Entity,6,实体名称,ProcessingInstruction,7,处理指令的目标,Comment,8,#comment,Document,9,#document,DocumentType,10,文档类型名称,DocumentFragment,11,#document-fragment,Notation,12,DTD,定义标记的名称,【,例,7-10】,ex8.html,图,7-6,例,7-10,输出结果图,7.2.
17、5,创建节点,DOM,标准中用于创建节点的方法包括:,(,1,),createElement,方法:创建,HTML,元素;,(,2,),createTextNode,:,创建文本节点;,(,3,),createDocumentFragment,方法:创建,DOM,文档片段;,(,4,),cloneNode,方法:通过复制已有节点创建新节点。,1,createElement,方法,createElement,方法用于在,HTML,文档中创建新的元素。,考虑例,7-11,所示的,HTML,页面。,【,例,7-11,】,ex9.html,(,HTML,部分),【,例,7-12】,ex9.html,(
18、JavaScript,部分),图,7-7,例,7-12,输出结果图,2,createTextNode,方法,createTextNode,方法可以用于创建一个新的文本节点。,现在改变“新增”按钮的功能:每次新增按钮的同时还要添加一些说明文字。,具体实现方式是修改,add,方法,在其中使用,createTextNode,方法创建文本节点,然后附加到,元素中,如例,7-13,所示。,【,例,7-13,】,ex9.html,(,JavaScript,部分),图,7-8,例,7-13,输出结果图,3,createDocumentFragment,方法,createDocumentFragment,方
19、法可以创建一个文档片段(,DocumentFragment,),,在文档片段中可以添加各种节点,最后一次性添加到,HTML,页面中。,使用这种方式可以减少页面更新的次数,提高页面展示的效率。,【,例,7-14】,ex9.html,(,JavaScript,部分),图,7-9,例,7-14,输出结果图,【,例,7-15,】,ex10.html,(,HTML,部分),【,例,7-16,】,ex10.html,(,JavaScript,部分),图,7-10,例,7-15,、例,7-16,输出结果图,4,cloneNode,方法,cloneNode,方法使得我们可以在,DOM,使用“模板”方式创建节点
20、这对于需要在页面中创建大量类似节点的情况特别有用。,可以首先创建一个“模板”节点,创建新节点时首先调用,cloneNode,方法获得“模板”节点的副本,然后根据实际应用的需要对该副本节点进行局部内容的修改。,使用,cloneNode,方法是一种非常高效的创建节点的方式。,考虑例,7-17,所示的,HTML,页面,现在希望在页面中添加类似的内容(标题,+,文本内容)。,【,例,7-17,】,ex11.html,(,HTML,部分),(,a,),页面初始状态,(,b,),添加内容后的页面,图,7-11,使用,cloneNode,方法创建新节点,【,例,7-18】,ex11.html,(,Java
21、Script,部分),7.2.6,操作节点,操作,DOM,节点可以使用标准的,DOM,方法,如,appendChild,(),,,removeChild,(),等,也可以使用非标准的,innerHTML,属性。,我们一直在强调使用,DOM,定义的方法和属性,但,innerHTML,属性是一个例外。,1,使用,DOM,标准方法,DOM,中可以使节点发生变化的常用方法包括:,(,1,),appendChild,:,为当前节点新增一个子节点,并且将其作为最后一个子节点;,(,2,),insertBefore,:,为当前节点新增一个子节点,将其插入到指定的子节点之前;,(,3,),replaceChi
22、ld,:,将当前节点的某个子节点替换为其他节点;,(,4,),removeChild,:,删除当前节点的某个子节点。,【,例,7-19,】,ex12.html,(,HTML,部分),(,a,),页面初始状态,(,b,),删除、修改,DOM,节点后的页面,图,7-12,删除和修改,DOM,节点,【,例,7-20】,ex12.html,(,JavaScript,部分),2,使用,innerHTML,属性,上面介绍了多种访问和操作,DOM,节点的方法,这些方法的基础是,DOM,树结构,它们完成的功能不外乎对树形结构的修改。,这类方法并不适用于所有的应用场景,有些情况下可能会要求直接修改节点的,HTM
23、L,代码,而不关心,DOM,树结构如何修改。,在这种情况下应该使用,innerHTML,属性对节点进行操作。,例,7-21,是一个,HTML,页面的代码,页面最初的显示效果如图,7-13,(,a,),所示。,【,例,7-21,】,ex13.html,(,HTML,部分),(,a,),页面初始状态,(,b,),修改后的页面,图,7-13,innerHTML,属性,【,例,7-22】,ex13.html,(,JavaScript,部分),7.3 DOM,应用示例,在,Web,编程中,,DOM,几乎无处不在,本章将根据实际应用开发中经常遇到的场景,提供相应的解决方案。,7.3.1,文本框自动获得焦点
24、在浏览网站时经常需要在输入框中输入文字,例如用户登录页面,搜索页面等。很多注重用户体验的网站往往会使页面中的文本框自动获得焦点,免去了用户用鼠标单击输入框进行输入的不便。,本节将模拟一个用户登录的页面,在其中实现该功能。,登录页面,HTML,代码如例,7-23,所示。,【,例,7-23,】,autofocus.html,(,HTML,部分),图,7-14,文本框自动聚焦,【,例,7-24】,autofocus.html,(,JavaScript,部分),7.3.2,表单输入验证,表单输入验证也是在,JavaScript,编程中经常需要实现的功能。,例如大多数网站对用户名的长度、密码的复杂程度
25、都有一定的要求,在用户填写表单时应对其输入内容进行必要的验证,尽可能地保证用户填写内容的正确性。,对于以上的登录页面,假设网站要求用户名长度大于,3,,可以通过以下的脚本在用户输入的同时给予相应的提示。,我们为“用户名”文本输入框添加,onblur,事件响应,当焦点离开文本框时对输入框的内容进行验证,在页面上输出相应的提示信息。,【,例,7-25】,form_verify.html,(,HTML,部分),【,例,7-26】,遍历所有的输入框,添加,onblur,事件响应函数,【,例,7-27】,为某个页面元素添加,onblur,事件响应函数,(,a,),验证成功,(,b,),验证失败,图,7-
26、15,表单输入校验,7.3.3,双向选择列表框,本节将要实现的是如图,7-16,所示的双向选择列表框。,在列表框中选择一个或者多个选项,通过相应的按钮操作可以将选项在两个列表框之间任意地移动。,双向选择列表框的优点是它可以以比较直观的方式进行相关选项的选择,类似的功能需求在很多网络应用中都会出现。,例,7-28,所示为双向选择列表框的,HTML,页面代码,其运行效果如图,7-16,(,a,),所示。,(,a,),初始状态,(,b,),移动选项后的列表框,图,7-16,双向选择列表框,【,例,7-28】,selects.html,(,HTML,部分),【,例,7-29】,moveRight,方法
27、例,7-30】,moveRightAll,方法,7.3.4,关键词链接,图,7-17,所示为,Wiki,网站中的一个页面(摘自,,/JavaScript,),,其中的关键词均以链接的形式呈现。类似的方式在其他网络应用中也十分常见。,实现这类页面有两种实现方式,一是直接修改,HTML,页面,将关键词部分替换为链接;二是通过,JavaScript,进行动态修改。,目前很多网站由于采用后台程序生成静态,HTML,页面,由后台程序完成链接的替换工作。,但某些网站的页面仍然需要手工的编辑,那么这样的修改就会非常繁琐。,无论自动修改还是手工修改,最终生成,HTML,页面的结构会变得非常零乱。本节将介
28、绍一种使用,JavaScript,增加关键词链接的方法,使用该方法可以在不修改页面,HTML,代码的情况下实现类似图,7-17,的效果。,首先来看原始的,HTML,页面代码,如例,7-31,所示。其中包括一段描述文字。,【,例,7-31,】,keywords.html,(,HTML,部分),图,7-17,Wiki,网站中的关键词链接,(,a,),原始页面,(,b,),添加关键词链接后的页面,图,7-18,添加关键词链接,7.3.5,可排序表格,在桌面应用实现可排序表格非常容易,有很多相关的控件可以使用,但是,HTML,中的表格元素不具备排序的能力。,但在,Web,应用中,我们经常需要实现按某一
29、列对表格排序的功能。,本节将介绍一种通用的方法,通过,JavaScript,实现表格的排序。,1,排序方法,对表格排序,实际是将表格内的各种数据进行排序,因此有必要了解在,JavaScript,中如何对各种类型的数据进行排序。,JavaScript,中对数组对象执行,sort,方法即可对数组内的元素进行排序,对于原始数据类型(字符串、数字、日期时间和布尔型),直接将值存入数组,执行,sort,方法即可获得有序的数组。,例如:,var,arr,=6,8,10,7,9;/,无序数组,arr.sort();/,arr,为,6,7,8,9,10,很多情况下对同一个排序字段需要进行正序和逆序排列,对于正
30、序的数组可以直接调用,reverse,方法进行逆序排列。,例如:,var,arr,=6,8,10,7,9;/,无序数组,arr.sort();/,arr,为,6,7,8,9,10,arr.reverse();/,arr,为,10,9,8,7,6,除了综合使用,sort,和,reverse,方法对数组进行逆序排列之外,还可以通过指定比较函数的方式实现逆序排列。,2,比较表格中的两行,JavaScript,原始数据类型的排序方式可以扩展到任意类型的数据,甚至页面中的,DOM,元素也可以进行排序,前提是为它们指定一个合理的比较规则,即如何实现以下形式的比较函数:,function,compTr(tr
31、A,trB,),.,对表格中的行进行比较时需要确定以下,3,个因素:,(,1,)表格排序字段,(,2,)排序字段的数据类型,(,3,)排序方式(正序或者逆序),下面将根据这,3,个因素生成相应的,compTr,函数,生成,compTr,函数的方法声明如下:,function,createComp(col,type,inverse),3,表格排序,表格中的行保存在表格节点的,rows,集合对象中,,rows,集合并非,Array,对象,因此要对表格进行排序首先要将表格的每一行保存在数组对象中。,下面介绍的,sort,方法采取的方式是将,rows,对象中相对应的元素依次取出,存入数组,allTr,
32、中,然后对数组中的元素进行排序(当然在,allTr,中进行排序不会对页面显示产生影响);接下来创建一个文档片段,在,sort,方法中将,allTr,数组中的元素依次附加到文档片段中;最后将文档片段附加到表格内部,从而使表格中所有的行都按照排序后的顺序显示。,【,例,7-32】,sorttable_1.html,(,a,),未排序的表格,(,b,),排序后的表格,图,7-19,表格排序,【,例,7-33,】,sorttable_2.html,(,JavaScript,部分),(,a,),按字符串字段排序,(,b,),按数字字段排序,(,c,),按日期时间字段排序,(,d,),按布尔型字段逆排序,图,7-20,表格排序,小 结,本章首先对,DOM,标准进行了介绍,讲解了如何使用,JavaScript,进行,DOM,编程,然后结合常见的应用场景,通过多个示例说明如何通过,DOM,编程解决,Web,应用开发中的一些实际问题,如表格排序、表单验证、添加关键词链接等。,本章的示例不仅仅限于解决某个具体的问题,同时也尽可能地提供通用的解决方案,提高代码的可复用程度。,






