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

相關文章
相關標籤/搜索