ADS3.8 DOM2核心和DOM2 HTML——Node对象之六:操作DOM节点树

前端技术 everyinch 1875℃ 0评论

大多数DOM脚本的任务就是在DOM文档中插入、删除和移动节点。其中appendChild()和insertBefore()是常用的方法。下面是appendChild()方法的示例:

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);
});

appendChild()方法是把新节点添加到列表的末尾,而insertBefore()则是在某个节点之前插入新节点。例如下面的示例是在sample.html的列表中的最后一个节点之前插入一个新节点:

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);
});

在W3C的规范中并不包含prependChild()和insertAfter()方法,在JavaScript最佳实践——命名空间和自定义库中,实现了这两个函数,这里再次列出实现的代码:

/**
 * 在元素中追加子节点,即在头部插入子节点
 */
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;

insertAfter()方法的实现如下:

/**
 * 在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;

对于替换和删除一个节点的操作,可以使用replaceChild(newChild, oldChild)和removeChild(oldChild)方法来实现。例如,通过下面的代码将sample.html中的Firefox列表项替换成一个新节点:

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);
});

而要删除Firefox列表项,只需要在相应节点的父节点上调用removeChild()方法即可:

ADS.addEvent(window, 'load', function() {
    ADS.log.header('Remove a node');
    var firefoxLi = document.getElementById('firefoxListItem');
    firefoxLi.parentNode.removeChild(firefoxLi);
});

DOM新手常犯的一个错误是没有理解document.getElementById()方法返回的是对Node对象的引用,而不是相应对象的副本。如果运行下面的代码会有几个Firefox列表项呢?

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);
});

正确的答案是2个,即在列表底部有两个Firefox条目,位于上面的Firefox条目则消失了。这是因为通过document.getElementById()方法取得并把节点赋值给firefoxLi变量后,实际上取得是一个指向该节点的引用,而非节点的副本:

var firefoxLi = document.getElementById('firefoxListItem');

随后,当把这个引用添加到列表中时,appendChild()方法会取得引用的节点并将它添加到无序列表的末尾:

unorderedList.appendChild(firefoxLi);

也就是说,添加的是已经在文档中存在的一个节点的引用,所以节点被移动到了新位置。



转载请注明:陈童的博客 » ADS3.8 DOM2核心和DOM2 HTML——Node对象之六:操作DOM节点树

喜欢 (0)
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

无觅相关文章插件,快速提升流量