先来看一张简单的文档树
树的顶层节点是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