文档对象模型(通常称为 DOM)为 XML 文档的已解析版本定义了一组接口。解析器读入整个文档,然后构建一个驻留内存的树结构,然后您的代码就可以使用 DOM 接口来操作这个树结构。您可以遍历树以了解原始文档包含了什么,您可以删除树的几个部分,还可以重新排列树和添加新的分支,等等。
DOM 问题 |
DOM 提供了一组丰富的功能,您可以用这些功能来解释和操作 XML 文档,但使用它们是有代价的。在开发用于 XML 文档的原始 DOM 时,XML-DEV 邮件列表上的许多人提出了 DOM 的几个问题:
- DOM 构建整个文档驻留内存的树。如果文档很大,就会要求有极大的内存。
- DOM 创建表示原始文档中每个东西的对象,包括元素、文本、属性和空格。如果您只需关注原始文档的一小部分,那么创建那些永远不被使用的对象是极其浪费的。
- DOM 解析器必须在您的代码取得控制权之前读取整个文档。对于非常大的文档,这会引起显著的延迟。
这些仅仅是由文档对象模型的设计引起的问题;撇开这些问题,DOM API 是解析 XML 文档非常有用的方法。
DOM常用功能及常用函数介绍 收藏
先来看一张简单的文档树
树的顶层节点是NodeA节点,下面的伪代码反应了树中节点的相互关系:
NodeA.firstChild = NodeA1
NodeA.lastChild = NodeA3
NodeA.childNodes.length = 3
NodeA.childNodes[0] = NodeA1
NodeA.childNodes[1] = NodeA2
NodeA.childNodes[2] = NodeA3
NodeA1.parentNode = NodeA
NodeA1.nextSibling = NodeA2
NodeA3.prevSibling = NodeA2
NodeA3.nextSibling = null
NodeA.lastChild.firstChild = NodeA3a
NodeA3b.parentNode.parentNode = NodeA
DOM提供了一些方法,用来操作一个文档树的节点结构,可以执行"插入节点","更新节点","删除节点","克隆节点"等常用操作 函数名称 功能描述
insertBefore() 在参考子节点之前插入一个新的子节点.如果参考的子节点为null,则新的子节点将作为调用节点的最后一个子节点插入
replaceChild() 在childNodes集合中使用指定的newChild来代替oldChild;如果代替成功,则返回oldChild;如果newChild是null,那么就删除oldChild
removeChild() 从节点的ChildNodes集合中删除指定的节点,如果删除成功,则返回删除的子节点
appendChild() 添加一个新节点到childNodes集合的末尾,如果成功,则返回新节点
cloneNode() 创建一个新的、复制的节点,并且如果传入的参数是true时,还将复制子节点,如果节点是一个元素,那么还将复制相应属性,返回新的节点
树中的节点可以分为"元素型节点(element node)"和"文字型节点(text node)"
"元素型节点(element node)"对应于文档中的某个“标签”,它可以拥有“属性”,它的内部可以包容“子节点”。
"文字型节点(text node)"对应于文档中的纯文字内容,它在文档中没有任何对应的“标签”,不可以包容“子节点”。
"元素型节点(element node)"和"文字型节点(text node)"的“访问方法”,“创建方法”是不同的。但是“删除方法”是一样的。
元素型节点(element node)
访问element node
可以用下面这些方法:
利用节点间的相互关系,从一个节点跳转到另一个节点,直到跳到我们想要的目标节点,主要用到了firstChild,parentNode等
getElementById()
getElementsByTagName()
下面详细说明这些方法:
使用节点间的相互关系来定位到某个元素节点
例子1:
<html>
<head>
<title></title>
</head>
<body><p>这是一段文字.</p>
<script language="JavaScript">
alert(document.documentElement.lastChild.firstChild.tagName);
</script>
</body>
</html>
结果将会显示"p",下面是一些解释
document.documentElement
得到 html tag.
lastChild
得到 body tag
firstChild
得到 body 中的第一个节点,也就是 p tag
tagName
得到 节点的标签名, "p"
例子2:
<html>
<head>
<title></title>
</head>
<body>
<p>这是一段文字.</p>
<script language="JavaScript">
alert(document.documentElement.lastChild.firstChild.tagName);
</script>
</body>
</html>
这个例子和上面相比,仅仅是在“body标签”后面多加了一个空行,但是在firefox中,会把空行看作是一个节点,所以返回值是"undefined",而在IE中将跳过空行仍然指向P标签
使用 document.getElementById() 访问元素节点
首先给需要访问的节点设置id值
<p id="段落">这是一段文字.</p>
然后把节点的id值传给document.getElementById()函数,从而得到相应的节点
alert(document.getElementById("段落").tagName);
这种方法你不用关心节点在文档树的哪一个地方,而只要保证在页面中它的id值是唯一的就可以了
使用 document.getElementsByTagName(标签名)[n] 来访问元素节点
document.getElementsByTagName(标签名)的返回值是一个数组,例如你可以通过下面的例子改变整个页面的连接
var nodeList = document.getElementsByTagName("a");
for (var i = 0; i < nodeList.length; i++)
nodeList[i].style.color = "#ff0000";
创建element node
创建前的代码
<p id="段落">这是一段文字.</p>
var span_text = document.createElement("span");
span_text.appendChild(document.createTextNode("这是新添加的文字."));
document.getElementById("段落").appendChild(span_text);
文字型节点(text node)
访问text node
text node不像element node那样具有id属性,所以它不能通过document.getElementById()来访问.
text node在文档中没有对应任何的“标签”,所以它不能通过document.getElementsByTagName()来访问
因此,只能利用节点间的相互关系来定位到某个text node
例子1:
<p id="段落">这里是段落的初始文字</p>
文档结构:p标签中的文字串这里是段落的初始文字构成了text node,它是p元素唯一的孩子,可以通过firstChild来访问.
下图反应了文档结构
访问text node的js:
alert(document.getElementById("段落").firstChild.nodeValue);
注释:利用nodeValue属性可以得到text node对应的"文字内容",但是这个属性不能用于element node,例如alert(document.getElementById("段落").nodeValue);是错误的.
例子2:(文档结构更复杂一点)
<p id="段落">这里是段落的<b>初始</b>文字</p>
文档结构:p元素有3个孩子,
这里是段落的构成了一个text node
<b>初始</b>构成了element node
文字构成了一个text node
下图反应了文档结构
在这里通过document.getElementById('段落').firstChild.nodeValue将仅仅得到这里是段落的,不包括<b>初始</b>文字.
也可以这样用
document.getElementById('段落').firstChild.nodeValue ="<b>新的</b>文字";其中的html代码将不会被解释,浏览器将把他们当成普通的文本来显示
创建text node:
var new_TextNode = document.createTextNode("新添加的文字");
上面的代码创建了一个新的text node,但是它还不是文档树的一部分,要让它显示在页面上就必须让它成为文档树中某一个节点的child,因为text node不能有儿子,所以你不能将它加入到一个text node中,只能把它加入到element node中
<p id="段落">这里是段落的初始文字</p>
下面的代码建立了一个新的text node并且通过appendChild()方法将其加入到childNodes数组的末尾
var new_TextNode = document.createTextNode("新添加的文字");
var el = document.getElementById("段落");
el.appendChild(new_TextNode);
删除text node:
var el = document.getElementById("段落");
if(el.hasChildNodes())
el.removeChild(el.lastChild);首先判断父节点是否还有child,以阻止当其没有child的时候调用removeChild()产生错误
attribute
attribute对象和元素相关,但不是文档树的子节点.
访问attribute
你可以在html标签中定义自己的属性:
<p id="段落" myAttribute="myValue">这里是段落的文字</p>
然后使用getAttribute()得到这个属性的取值
alert(document.getElementById("段落").getAttribute("myAttribute"));
返回值将是"myValue".但是请注意这里必须使用getAttribute()函数,而不是AttributeName,因为有一些浏览器并不支持自定义属性
创建attribute
有三种方法可以为元素建立新的属性
var attr = document.createAttribute("myAttribute");
attr.value = "myValue";
var el = document.getElementById("段落");
el.setAttributeNode(attr);var el = document.getElementById("段落");
el.setAttribute("myAttribute", "myValue");var el = document.getElementById("段落");
el.myAttribute = "myValue";删除attribute
attribute也可以从一个元素中删除,你可以使用removeAttribute()或者将element.attributeName指向一个null值.
改变attribute的值
例子1:
<p id="段落" align="left">这里是段落的文字</p>
使用setAttribute(属性名称,属性值)来改变某个属性的值
document.getElementById('段落').setAttribute('align', 'right');
例子2:
<p id="段落" style="text-align:left;">这里是段落的文字</p>
修改元素的style中的text-align子属性.
document.getElementById('段落').style.textAlign = 'right';
注释:dom中的textAlign对应于style的text-align子属性。有一条基本规律:如果style的子属性名字中出现"-"符号,则在dom中会被去掉并且随后的一个字母改为大写,例如:dom中的backgroundColor对应于background-color
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/gang_gang_gang/archive/2008/11/29/3408127.aspx