七(4) . 最常见的JavaScript DOM方法实战-创建和克隆元素

JavaScript DOM 创建和克隆元素

W3C DOM允许你创建自己的元素和文本节点,并把它们添加大文档树中。理论上上说,你可以从树中移除所有的元素,创建新元素,或者重整文档树,从而完全改变页面。但是在实践中,这个特性用起来有些限制。

DOM也允许你克隆现有的元素,已便你能方便地复制文档的某一部分并在文档中分发副本。

在我们学习之前,我还是把总结好的DOM知识体系表放在前面以方便我们查阅。

Node接口定义的节点类型都包含的特性和方法

特性和方法后面的 “冒号:” 紧跟的单词是“返回值类型

Node
属性

遍历节点(短途旅行):
parentNode : Node
firstChild : Node
lastChild : Node
nextSibling : Node
previousSibling : Node
childNodes : NodeList
节点信息:
nodeName :String
nodeType :number
nodeValue :String
返回一个节点的根元素(文档对象):
ownerDocument : Document
包含了代表一个元素的特性的Attr对象;仅用于Element节点:
attributes : NamedNodeMap
获取对象层次中的父对象:
parentElement [IE] :Node
方法

修改文档树:
appendChild(Node newChild) : Node
insertBefore(Node newChild, Node refChild) : Node
removeChild(Node oldChild): Node
replaceChild(Node newChild, Node refChild) : Node
克隆一个节点:
cloneNode(boolean deep) : Node
删除一个子节点:
removeNode(boolean removeChildren) : Node
判断childNodes包含是否包含节点:
hasChildNodes() : boolean

Node

Document
属性

自己的:
documentElement : Element
继承 Node :
attributes, childNodes, firstChild, lastChild, nextSibling, nodeName, nodeType, nodeValue, ownerDocument, parentElement, parentNode, previousSibling
方法

自己的:
创建元素:
createElement(String tagName) : Element
createTextNode(String data) : Text
查找元素:
getElementById(String elementId) : Element
getElementsByTagName(String tagname) : NodeList
继承 Node :
appendChild, cloneNode, hasChildNodes, insertBefore, removeChild, removeNode, replaceChild

Element
属性

自己的:
tagName: String
继承 Node :
attributes, childNodes, firstChild, lastChild, nextSibling, nodeName, nodeType, nodeValue, ownerDocument, parentElement, parentNode, previousSibling
方法

自己的:
属性的读写:
getAttribute(String name) : String
setAttribute(String name, String value) : void
其它:
getElementsByTagName(String name) Stub : NodeList
normalize() Stub : void
removeAttribute(String name) : void
继承 Node :
appendChild, cloneNode, hasChildNodes, insertBefore, removeChild, removeNode, replaceChild

createElement()和createTextNode()

createElement()和createTextNode()做的事情正如它们的名字所说的那样。
我在 第七(3) . 最常见的JavaScript DOM方法实战-修改文档树中已经用过它们。

当时的目的是把新创建的元素添加到文档树里,使它成为某个元素的最后一个子节点。

1
2
3
4
5
6
 //创建一个li新元素
 var newChild=document.createElement('li');
 //创建一个a 新元素
 var newLink=document.createElement('a')
 //创建一个 Text 节点
 var newText=document.createTextNode('My Wiki');

newChild指向新创建的<li>元素对象,newLink指向新创建的<a>元素对象,而newText指向新创建的文本节点对象。
这些节点都还没有被插入文档中。正如我们上章 七(3) . 最常见的JavaScript DOM方法实战-修改文档树
中,用到的appendChild()或insertBefore()将它们附加到文档树中。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  var nav=document.getElementById("nav");
  //创建一个li新元素
  var newChild=document.createElement('li');
  //创建一个a 新元素
  var newLink=document.createElement('a')
  //创建一个 Text 节点
  var newText=document.createTextNode('My Wiki');
  //把Text添加到a元素节点中
  newLink.appendChild(newText);
  //给a元素节点设置属性href和内容
  newLink.setAttribute('href',"#");
  //把a元素节点添加到新的li元素节点中
  newChild.appendChild(newLink);
  //把新的li元素节点添加到 ul 元素节点里
  nav.appendChild(newChild);

这先将文本节点附加到<a>中,然后再将包含文本节点的<a>附加到<li>中,最后把包含<a>和文本的<li>附加到<ul>中。此时我的导航条ul中多了一个 li 子节点。

createTextNode()和HTML实体

createTextNode()有一个问题:

它不能创建类似于&euro;(€ 欧元符号)&yen;(¥ 人民币符号) © (&copy; 版权符号)&#8220;(“左双引号)&#8221;(” 右双引号)等,这样的HTML实体元素。

它会按字面创建文本,而不是创建你所需要的符号 。

1
2
3
4
5
6
<script  type="text/javascript">
window.onload=function(){
	var x=document.createTextNode("&copy; Copyrights reserved");
	document.getElementById("test").appendChild(x);
}
</script>

createTextNode 

不过,我们可以使用innerHTML来代替:

1
2
3
4
5
<script  type="text/javascript">
window.onload=function(){	
	document.getElementById("test").innerHTML="&copy; Copyrights reserved";
}
</script>

createTextNode or innerHTML

关于innerHTML属性的用法,我们会在下一节中作为专题来具体的讨论。

cloneNode()

cloneNode()方法克隆一个节点,即它能对节点做一个完美的复制,使你可以在随后将其插入到文档树中

我还是以我的导航条为例说明:

我的导航条 HTML代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<div id="menu">
    <h1>我的导航条</h1>          
    <ul id="nav">
       <li><a href="#">HOME</a></li>
       <li><a href="#">(X)Html / Css</a></li>
       <li><a href="#">Ajax / RIA</a></li>
       <li><a href="#">GoF</a></li>
       <li><a href="#">JavaScript</a></li>
       <li><a href="#">JavaWeb</a></li>
       <li><a href="#">jQuery</a></li>
       <li><a href="#">MooTools</a></li>
       <li><a href="#">Python</a></li>
       <li><a href="#">Resources</a></li>
    </ul>
</div>

测试cloneNode()

1
2
3
4
5
6
7
8
9
10
<script  type="text/javascript">
window.onload=function(){
     var nav_list=[];
	 var nav=document.getElementById("nav");
     nav_list=nav.getElementsByTagName("li");
	 var x=nav_list[0];
	 var y=x.cloneNode(true);
	 nav.appendChild(y);
}
</script>

要想正确的使用cloneNode(),你必须了解它的一下二个特征:

1. cloneNode()接受一个可选值为true或false的参数。True 表示克隆元素和它的所有子节点。False表示克隆元素但不包含它的子节点。通常,我们在实践中用true,我从来没有遇到过想要克隆一个节点但不包含它的子节点的情形。

2. cloneNode()不会克隆事件处理程序。这相当的让人恼火,不知道这个方法是怎么定义的(原因我也不知道)所以每次你克隆一个节点,你不得不在克隆上重新定义事件处理程序。

站点统计