DOM
DOM(文档对象模型)是针对HTML和XML文档的一个API(应用程序编程接口)。DOM描绘了一个层次化的节点树,允许开发人员添加、移除和修改页面的某一部分。
节点层次
文档节点是每个文档的根节点,文档节点有一个子节点即元素我们称为文档元素,文档元素是文档最外层的元素,文档中的其他元素都包含在文档元素中,每个文档只能有一个文档元素。
每一段标记都可以通过树中的一个节点来表示:HTML元素通过元素节点表示,特性(attribute)通过特性节点表示,文档类型通过文档类型节点表示,而注释则通过注释节点表示。总共12种节点类型,这些类型都继承自一个基本型。
Node类型
JavaScript中所有节点类型都继承自Node类型,因此所有节点类型都共享相同的基本属性和方法。每个节点都有一个nodeType属性,用于表明节点类型,节点类型的定义由以下12个数值常量来表示,
- Node.ELEMENT_NODE(1)
- Node.ATTRIBUTE_NODE(2)
- Node.TEXT_NODE(3)
- Node.CDATA_SECTION_NODE(4)
- Node.ENTITY_REFERENCE_NODE(5)
- Node.ENTITY_NODE(6)
- Node.PROCESSING_INSTRUCTION_NODE(7)
- Node.COMMENT_NODE(8)
- Node.DOCUMENT_NODE(9)
- Node.DOCUMENT_TYPE_NODE(10)
- Node.DOCUMENT_FRAGMENT_NODE(11)
- Node.NOTATION_NODE(12)
为了确保浏览器兼容,最好是将nodeType属性与数字值进行比较,确定节点类型
if(someNode.nodeType == 1){
alert("Node is an element");
}
对于元素节点,nodeName中保存的始终都是元素的标签名,而nodeValue的值则始终是null。
节点关系
每个节点都有一个childNodes属性,其中保存着一个NodeList对象。NodeList是一种类数组对象,用于保存一组有序的节点,可以通过位置来访问这些节点。例如:
var firstChild = someNode.childNodes[0];
var secondChild = someNode.childNodes.item(1);
var count = someNode.childNodes.length;
每个节点都有一个parentNode属性,该属性指向文档树中的父节点。
包含在childNodes列表中的每个节点相互之间是同胞节点,通过使用列表中的每个节点的previousSibling和nextSibling属性可以访问同一列表中的其他节点。
其中someNode.firstChild的值始终等于someNode.childNodes[0];而someNode.lastChild的值始终等于someNode.childNodes[someNode.childNodes.length-1]。
hasChildNodes()也是一个非常有用的方法,这个方法可以在节点包含一个或多个子节点的情况下返回true。
操作节点
appendChild()方法用于向childNodes列表的末尾添加一个节点,返回值是新增的节点。
var returnedNode = someNode.appendChild(newNode);
alert(returnedNode == newNode); //true
alert(someNode.lastChild == newNode); //true
insertBefore()方法把节点放在childNodes列表中某个特定的位置,这个方法接收两个参数,要插入的节点和作为参照的节点,返回值是插入的节点。
replaceChild()方法是替换文档树中的节点,该方法接收两个参数,要插入的节点和要替换的节点,返回值是被替换的节点。
removeChild()方法移除文档树中节点,该方法接收一个参数,要移除的节点,返回值是被移除的节点。
Document类型
JavaScript通过Document类型表示文档,在浏览器中,document对象是HTMLDocument的一个实例,表示整个HTML页面,document对象是window对象的一个属性,因此可以作为全局对象来访问。
Document节点具有以下特征:
- nodeType的值为9
- nodeName的值为“#document”
- nodeValue的值为null
- parentNode的值为null
- ownerDocument的值为null
查找元素
最常见的DOM应用,就是要取得特定的某个或某组元素的引用,然后再执行一些操作。
取得元素可以使用document对象的几个方法来完成,其中,Document类型为此提供了两个方法:getElementById()和getElementsByTagName()。
getElementById()接收一个参数,要取得元素的id,返回值是相应的元素。
getElementsByTagName()接收一个参数,要取得的元素标签名,返回值是包含零个或多个元素的NodeList。
HTMLCollection对象还有一个方法,叫做namedItem(),使用这个方法可以通过元素的name特性取得集合中的项。例如:
<img src="myimg.gif" name="myImage">
var myImage = images.namedItem("myImage");
var myImage = images["myImage"];
getElementsByName()方法会返回带有给定name特性的所有元素,该方法通常用于取得单选按钮。
文档写入
document对象通过write()、writeln()、open()、close()将输出流写入到网页。
write()和writeln()都接收一个字符串参数,即要写入到输入流中的文本。
open()和close()分别用于打开和关闭网页的输出流。如果在页面加载期间使用write()和writeln()方法,则不需要用到这两个方法。
Element类型
Element类型用于表现XML和HTML元素,提供了对元素标签名、子节点及特性的访问。Element节点具有以下特征:
- nodeType的值为1
- nodeName的值为元素的标签名
- nodeValue的值为null
- parentNode可能是Document或Element
要访问元素的标签名可以使用noeName属性或者tagName属性。
取得特性
每个元素都有一个或多个特性,这些特性的用途是给出相应元素或其内容的附加信息。
操作特性的DOM方法主要有3个:getAttribute()、setAttribute()、removeAttribute()。
getAttribute()接收一个参数就是特性的名称;
setAttribute()接收两个参数,要设置的特性名和值;
removeAttribute()接收一个参数就是特性的名称,用于彻底删除元素的特性。
创建元素
使用document.createElement()方法可以创建新元素,这个方法只接收一个参数,即要创建的元素标签名。可以在新元素上设置相应的特性,由于新元素尚未被添加到文档树中,因此设置这些特性不会影响浏览器的显示,要把新元素添加到文档树中,可以使用appendChild()、insertBefore()、或replaceChild()方法。
Text类型
文本节点由Text类型表示,包含的是可以照字面解释的纯文本内容。
Text节点具有以下特征:
- nodeType的值为3
- nodeName的值为“#text”
- nodeValue的值为节点所包含的文本
- parentNode是一个Element
- 没有子节点
可以通过nodeValue属性或data属性访问Text节点中包含的文本,这两个属性中包含的值相同。
可以通过下列方法操作节点中的文本:
- appendData(text):将text添加到节点末尾
- deleteData(offset,count):从offset指定为位置删除count个字符
- insertData(offset,text):从offset指定的位置插入text
- replaceData(offset,count,text):用text替换从offset指定的位置开始到offset+count为止处的文本
- splitText(offset):从offset指定位置将当前文本节点分成两个文本节点
- substringData(offset,count):提取offset指定的位置到offset+count为止处的字符串
除了这些方法,文本节点还有length属性,保存着节点中的字符数目。
空格也算一个文本节点
创建文本节点
可以使用document.createTextNode()创建新文本节点,这个方法接收一个参数,要插入的文本节点。不过此时在浏览器中是看不到创建的新文本节点,需要把新节点添加到文档树中已经存在的节点中。
规范化文本节点
如果在 一个包含两个或多个文本节点的父元素上调用normalize()方法,则会将所有文本节点合并成一个节点。
分割文本节点
splitText()方法会将一个文本节点分成两个文本节点,按照指定的位置分割nodeValue值,原来的文本节点将包含从开始到指定位置之前的内容,新文本节点将包含剩下的内容,这个方法会返回一个新文本节点,该节点与原节点的parentNode相同。
Comment类型
注释在DOM中是通过Comment类型来表示的。Comment节点具有以下特征:
- nodeType的值为8
- nodeName的值为“#comment”
- nodeValue的值是注释的内容
- parentNode可能是Document或Element
- 没有子节点
comment类型与text类型继承自相同的基类,因此它拥有除了splitText()之外的所有字符串操作方法,与Text类似,也可以通过nodeValue和data属性来取得注释的内容。
也可以使用document.createComment()为其传递注释文本创建注释节点。
CDATASection类型
CDATASection类型只针对基于XML的文档,表示CDATA区域,与Comment类似,CDATASection类型继承自Text类型,因此拥有除splitText()之外的所有字符串操作方法。具有以下特征:
- nodeType的值为4
- nodeName的值为”#cdata-section”
- nodeValue的值为CDATA区域中的内容
- parentNode可能是Document或Element
- 没有子节点
在XML文档中,可以使用document.createCDATASection()来创建CDATA区域,只需要为其传入节点的内容即可。
DocumentType类型
DocumentType包含与文档的doctype有关的所有信息。具有以下特征:
- nodeType的值为10
- nodeName的值为doctype的名称
- nodeValue的值是null
- parentNode是Document
- 没有子节点
DocumentFragment类型
DOM规定文档片段(document fragment)是一种轻量级的文档,可以包含和控制节点,但不会像完整的节点那样占用额外的资源。具有以下特征:
- nodeType的值为11
- nodeName的值为”#document-fragment”
- nodeValue的值为null
- parentNode的值为null
虽然不能把文档片段直接添加到文档中,但可以将它作为一个仓库来使用,即可以在里面保存将来可能会添加到文档中的节点,要创建文档片段,可以使用document.createDocumentFragment()方法。
Attr类型
元素的特性在DOM中以Attr类型来表示,在所有浏览器中都可以访问Attr类型的构造函数和原型。从技术角度讲,特性就是存在与元素的attributes属性中的节点,特性节点具有的特征:
- nodeType的值为2
- nodeName的值为特性的名称
- nodeValue的值是特性的值
- parentNode的值为null
尽管他们也是节点,但特性却不被认为是文档树的一部分,开发人员最常使用getAttribute()、setAttribute()、removeAttribute(),很少直接引用特性节点。