zoukankan      html  css  js  c++  java
  • DOM 节点的克隆与删除

    无奈的开头

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

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

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

             删除节点理应没有什么问题,但是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;
                }

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

        

  • 相关阅读:
    __all__ = ["a"]被调用时只会调用list里面的
    if __name__ == "__main__"
    异常处理
    python
    python传智播客笔记--第十天:隐藏属性,私有属性,私有方法,__del__方法,类的继承,类中方法的重写
    python获取引用对象的个数
    对象属性会保留
    python中的不定长参数
    python的全局变量
    python实现文件命名
  • 原文地址:https://www.cnblogs.com/accordion/p/4237505.html
Copyright © 2011-2022 走看看