5.3 改变元素的类型
有时候,需要完全改变一个元素的类型,但却还要保留原有的子节点结构。
方 法
并没有什么直接的、简单的方法来改变一个元素的类型。为了达到这个目的,需要一点点技巧。
假设想把下面的段改成div:
File: change_type_of_element.js (excerpt)
<p id="starLinks">
</p>
首先需要创建一个div元素,然后把段的所有子节点放到该元素中,将老元素用新元素换掉:
File: change_type_of_element.js (excerpt)
var div = document.createElement("div");
var paragraph = document.getElementByIdx("starLinks");
for (var i = 0; i < paragraph.childNodes.length; i++)
{
}
paragraph.parentNode.replaceChild(div, paragraph);
这里惟一让人感到陌生的大概就是那一行克隆段子节点的操作。cloneNode方法会创建一个完全一样的节点拷贝。参数true表明想克隆子节点本身。通过cloneNode创建了所有子节点的镜像,并放入新创建的div元素中,完成所有拷贝之后,再删掉那个段元素即可。
克隆节点的方法在某些情况下非常有用,不过这里有个更清爽的方法可以实现同样的功能。可以直接把段元素中的子节点移入新的div元素中。DOM节点在任何时候只能属于一个父节点,所以把子节点放入div元素中,也就意味着该节点从段元素中删除。
File: change_type_of_element2.js (excerpt)
var div = document.createElement("div");
var paragraph = document.getElementByIdx("starLinks");
while (paragraphNode.childNodes.length > 0){
}
paragraph.parentNode.replaceChild(div, paragraph);
更改DOM的节点结构时要当心 |
|
当DOM中发生变化时,集合中的元素会自动更新即使在变化发生之前已经将集合复制到一个变量中。所以,如果删掉了DOM中的某元素,而该元素属于一个正在使用的集合,那么集合中的该元素也会被删除。这会改变集合元素的数目,以及元素的序号。 在进行可能会更改DOM的节点结构的操作时例如将某节点移入到一个新节点中,必须警惕这个操作可能会影响到某些循环过程。例如while循环可能变得只能访问第一个子节点了,因为每次节点重定位,集合的长度都会递减。而for循环则不能正确地遍历所有的元素,因为for循环在循环过程中是假设集合的内容不会发生变化的。 |
讨 论
如果想将某元素的所有属性复制到它的替换元素中1,并没有什么简单的方法。为了让新元素拥有相同的id、class、href等,则必须手工复制这些值。
File: change_type_of_element.js (excerpt)
div.id = paragraph.getAttribute("id");
div.className = paragraph.className;