ADS3.8 DOM2核心和DOM2 HTML——Node对象之六:操作DOM节点树
大多数DOM脚本的任务就是在DOM文档中插入、删除和移动节点。其中appendChild()和insertBefore()是常用的方法。下面是appendChild()方法的示例:[code lang="js"]
ADS.addEvent(window, 'load', function() {
ADS.log.header('Append Child');
var newChild = document.createElement('LI')
newChild.appendChild(document.createTextNode('A new list item!'));
var list = document.getElementById('browserList');
list.appendChild(newChild);
});
[/code]
appendChild()方法是把新节点添加到列表的末尾,而insertBefore()则是在某个节点之前插入新节点。例如下面的示例是在sample.html的列表中的最后一个节点之前插入一个新节点:
[code lang="js"]
ADS.addEvent(window, 'load', function() {
ADS.log.header('Insert Before');
var newChild = document.createElement('LI')
newChild.appendChild(document.createTextNode('A new list item!'));
var list = document.getElementById('browserList');
list.insertBefore(newChild,list.lastChild);
});
[/code]
在W3C的规范中并不包含prependChild()和insertAfter()方法,在JavaScript最佳实践——命名空间和自定义库中,实现了这两个函数,这里再次列出实现的代码:
[code lang="js"]
/**
* 在元素中追加子节点,即在头部插入子节点
*/
function prependChild(parent,newChild) {
if(!(parent = $(parent))) return false;
if(!(newChild = $(newChild))) return false;
if(parent.firstChild) {
// 如果存在一个子节点,则在这个子节点之前插入
parent.insertBefore(newChild,parent.firstChild);
} else {
// 如果没有子节点,则直接添加子节点
parent.appendChild(newChild);
}
// 返回父元素,以便实现方法连缀
return parent;
}
window['ADS']['prependChild'] = prependChild;
[/code]
insertAfter()方法的实现如下:
[code lang="js"]
/**
* 在DOM节点之后插入节点
*/
function insertAfter(node, referenceNode) {
if(!(node = $(node))) return false;
if(!(referenceNode = $(referenceNode))) return false;
return referenceNode.parentNode.insertBefore(node, referenceNode.nextSibling);
};
window['ADS']['insertAfter'] = insertAfter;
[/code]
对于替换和删除一个节点的操作,可以使用replaceChild(newChild, oldChild)和removeChild(oldChild)方法来实现。例如,通过下面的代码将sample.html中的Firefox列表项替换成一个新节点:
[code lang="js"]
ADS.addEvent(window, 'load', function() {
ADS.log.header('Replace a node');
var newChild = document.createElement('LI')
newChild.appendChild(document.createTextNode('A new list item!'));
var firefoxLi = document.getElementById('firefoxListItem');
firefoxLi.parentNode.replaceChild(newChild,firefoxLi);
});
[/code]
而要删除Firefox列表项,只需要在相应节点的父节点上调用removeChild()方法即可:
[code lang="js"]
ADS.addEvent(window, 'load', function() {
ADS.log.header('Remove a node');
var firefoxLi = document.getElementById('firefoxListItem');
firefoxLi.parentNode.removeChild(firefoxLi);
});
[/code]
DOM新手常犯的一个错误是没有理解document.getElementById()方法返回的是对Node对象的引用,而不是相应对象的副本。如果运行下面的代码会有几个Firefox列表项呢?
[code lang="js"]
ADS.addEvent(window, 'load', function() {
ADS.log.header('Clone and Move a Node');
var firefoxLi = document.getElementById('firefoxListItem');
var firefoxLiClone = firefoxLi.cloneNode(true);
var unorderedList = firefoxLi.parentNode;
// 添加到列表中
unorderedList.appendChild(firefoxLi);
// 添加到列表中
unorderedList.appendChild(firefoxLiClone);
});
[/code]
正确的答案是2个,即在列表底部有两个Firefox条目,位于上面的Firefox条目则消失了。这是因为通过document.getElementById()方法取得并把节点赋值给firefoxLi变量后,实际上取得是一个指向该节点的引用,而非节点的副本:
[code lang="js"]
var firefoxLi = document.getElementById('firefoxListItem');
[/code]
随后,当把这个引用添加到列表中时,appendChild()方法会取得引用的节点并将它添加到无序列表的末尾:
[code lang="js"]
unorderedList.appendChild(firefoxLi);
[/code]
也就是说,添加的是已经在文档中存在的一个节点的引用,所以节点被移动到了新位置。
查看完整版本: ADS3.8 DOM2核心和DOM2 HTML——Node对象之六:操作DOM节点树
Tags: