DOM 节点的克隆与删除

无奈的开头

        关于DOM节点操做,若是仅仅是根据标准API来操做,那是最简单不过的了。可是现实中却哪有这么容易的问题让咱们解决,其实不单单是节点的克隆与删除,节点的添加也是如此,并且添加节点须要考虑的状况更多,这里不详细讲解,只说明大概过程。node

        问题那么多,主要出如今浏览器自身实现上,其中尤属legacy IE上—IE6,7,8. 在添加节点的API实现上,IE作了一个贡献,那就是insertAdjacentHTML函数被归入HTML5规范上,这个函数在以前的文章中详细讲解并实现过,不提。此后,IE的行为却不值得提倡,由于咱们的兼容性主要针对的就是legacy IE。浏览器

        克隆节点,规范的API是cloneNode(boolean),boolean为true时进行深克隆。可是legacy IE却有一个奇怪的bug,那就是经过该方法克隆的副本,却仍含有相关的事件处理函数和用户自定义属性,并且修改删除这些属性或者函数,会影响到源节点的属性生病。。。着实让人无语。解决方案另辟蹊径,便可以经过获取副本的HTML字符串,从新构造一个DOM节点,这样根据字符串反系列化的副本就不会包含在js中额外操做的属性或者事件处理程序。app

         删除节点理应没有什么问题,可是legacy IE下仅仅使用removeNode会出现内存泄露问题,被删除的节点有部份内存并不会被回收,若是长时间运行该程序,则可能会出现内存耗尽的危险,只有关闭页面才可能回收这些内存。可是能够利用outerHTML属性作文章,他能够更有效的删除占用的内存,可是须要注意的是这种方法仍然不会彻底释放占用的内存,可是整体回收的内存大于removeNode方法。函数

实现

    /**
           * 旧版IE(IE678)拷贝元素节点,会连同事件处理函数和用户自定义属性一同拷贝给
             * 副本,而且修改副本的事件处理函数和自定义属性会影响到源节点。
             */
            clone =  function(){
                // 若是是IE678下的bug
                var el,c;
                if(Screen.support.cloneNodeWithHandler){
                    el = this[0].cloneNode(true);
                    c = doc.createElement("div");
                    c.appendChild(el);
                    return S.DomParser(c.innerHTML).firstChild;
                }else{
                    return this.cloneNode(true);
                }
            }
            remove =  function(){
                this.each(function(el){
                    if(el.nodeType && el.nodeType == 1){
                        S._unData(el);
                        if(el.parentNode){
                            el.parentNode.removeChild(el);
                        }
                        // IE 678下这样会形成内存泄露,元素节点删除以后
                        // 仍有部份内存不能回收。可经过outerHTML回收,可是
                        // 须要知道的是这种方法也不能回收节点使用的所有内存,可是
                        // 最起码回收的比removeChild多。
                        if(typeof el.outerHTML !== undefined){
                            el.outerHTML = "";
                        }
                    }
                });
                return this;
            }

 

上述代码是本人私人库实现的一部分,有错误之处还请指出。this

相关文章
相关标签/搜索