一、前言
當需要新元素時我們可以通過 document.createElement 接口來創建一個全新的元素,也可以通過克隆已有元素的方式來獲取一個新元素。而在部分瀏覽器中,通過復制來獲取新元素的效率比通過 document.createElement 方式的要高一些,具體的性能比較如下:
2% in IE8, but no change in IE6 and IE7
Up to 5.5% in Firefox 3.5 and Safari 4
6% in Opera (but no savings in Opera 10)
10% in Chrome 2 and 3% in Chrome 3
本篇將記錄元素克隆、和剪切的相關技術,以便日后查閱。
目錄一坨:
2. appendChild、insertBefore和replaceChild
五、題外話——IE獨有的replaceNode和swapNode方法
瀏覽器支持:所有瀏覽器均支持。
作用:拷貝元素自身。
API規范: {Node} Node.clone({boolean} [isDeep=false]) ,默認情況下僅拷貝元素本身,若入參為true時拷貝子孫元素也將被一同拷貝。
實際測試效果:
瀏覽器 | 復制子元素 | 標準屬性(property) | 標準特性(attribute) | 自定義特性(customize attribute) | 自定義屬性(expando) | DOM0事件處理函數 | DOM2事件處理函數 |
parentNode和 parentElement的值 |
ownerDocument |
IE5.5~8 | √ | √ | √ | √ | √(淺復制) | Χ | Χ | null | 不變 |
IE9+ | √ | √ | √ | √ | Χ | Χ | Χ | null | 不變 |
Chrome | √ | √ | √ | √ | Χ | Χ | Χ | null | 不變 |
FF | √ | √ | √ | √ | Χ | Χ | Χ | null | 不變 |
注意:
1. 使用cloneNode會將id特性也復制,因此需要手動修改副本的id特性。
2. {Document} document和{HTMLDocument} document.documentElement也可以調用cloneNode方法拷貝自身,并且支持深拷貝。
3. 當從其他文檔中拷貝元素,元素副本的ownerDocument依然為其他文檔的document對象,直到我們將元素副本添加到當前文檔下,ownerDocument屬性才會變化。
瀏覽器支持:IE9+和其他現代瀏覽器均支持。
作用:拷貝其他文檔中的元素到當前文檔中。(https://developer.mozilla.org/en-US/docs/Web/API/document.importNode)
API規范: {Node} document.importNode({HTMLElement|HTMLDocument|HTMLDocumentFragment} externalNode [, {boolean} isDeep=true])
實際測試效果:
瀏覽器 | 復制子元素 | 標準屬性(property) | 標準特性(attribute) | 自定義特性(customize attribute) | 自定義屬性(expando) | DOM0事件處理函數 | DOM2事件處理函數 |
parentNode和 parentElement的值 |
ownerDocument |
IE9+ | √ | √ | √ | √ | Χ | Χ | Χ | null | 當前文檔的document對象 |
Chrome | √ | √ | √ | √ | Χ | Χ | Χ | null | 當前文檔的document對象 |
FF | √ | √ | √ | √ | Χ | Χ | Χ |
null | 當前文檔的document對象 |
注意:
1. 使用importNode會將id特性也復制,因此需要手動修改副本的id特性;
2. 不接受{Document} document的拷貝;
3. 雖然規范中描述其作用為拷貝其他文檔中的元素,但實際上是可以對當前文檔的元素進行拷貝的;
4. 當從其他文檔中拷貝元素,元素副本的ownerDocument自動設置為當前文檔的document對象。
瀏覽器支持:IE9+和其他現代瀏覽器均支持。
作用:剪切其他文檔中的元素到當前文檔中。(https://developer.mozilla.org/en-US/docs/Web/API/document.adoptNode)
API規范: {Node} document.adoptNode({HTMLElement|HTMLDocument|HTMLDocumentFragment} externalNode)
實際測試效果:
瀏覽器 | 復制子元素 | 標準屬性(property) | 標準特性(attribute) | 自定義特性(customize attribute) | 自定義屬性(expando) | DOM0事件處理函數 | DOM2事件處理函數 |
parentNode和 parentElement的值 |
ownerDocument |
IE9+ | √ | √ | √ | √ | √ | √ | √ | null | 當前文檔的document對象 |
Chrome | √ | √ | √ | √ | √ | √ | √ | null | 當前文檔的document對象 |
FF | √ | √ | √ | √ | √ | √ | √ | null | 當前文檔的document對象 |
注意:
1. 不接受{Document} document的剪切,但可以對{HTMLDocument} document.documentElement進行剪切;
2. 雖然規范中描述其作用為拷貝其他文檔中的元素,但實際上是可以對當前文檔的元素進行拷貝的;
3. 當從其他文檔中拷貝元素,元素副本的ownerDocument自動設置為當前文檔的document對象。
2. appendChild、insertBefore和replaceChild
我們知道appendChild、insertBefore和replaceChild操作元素時會切斷元素原來的位置關系,然后將其添加到新的樹層級結構中。這不就是元素的剪切操作嗎!于是我們可以通過appendChild、insertBefore和replaceChild方法將目標元素剪切到一個未加入DOM樹的元素中,即可模擬document.adoptNode的功能了。
;(function(doc){ var clipboard doc.adoptNode = doc.adoptNode || (clipboard = document.createElement('div'), function(node){ clipboard.appendChild(node) return clipboard.lastChild }) }(document))
實際測試效果:
瀏覽器 | 復制子元素 | 標準屬性(property) | 標準特性(attribute) | 自定義特性(customize attribute) | 自定義屬性(expando) | DOM0事件處理函數 | DOM2事件處理函數 |
parentNode和 parentElement的值 |
ownerDocument |
IE9+ | √ | √ | √ | √ | √ | √ | √ | 充當
clipboard
|
當前文檔的document對象 |
Chrome | √ | √ | √ | √ | √ | √ | √ | 充當
clipboard |
當前文檔的document對象 |
FF | √ | √ | √ | √ | √ | √ | √ | 充當
clipboard |
當前文檔的document對象 |
注意:
1. 不接受{Document} document和{HTMLDocument} document.documentElement的剪切,但可以對{HTMLBodyElement} document.body進行剪切;
2. 當從其他文檔中拷貝元素,元素副本的ownerDocument自動設置為當前文檔的document對象。
上述的元素拷貝操作均無法拷貝自定義屬性和事件處理綁定,而jQuery的clone函數可實現這一點。
尊重原創,轉載請注明來自:http://www.cnblogs.com/fsjohnhuang/p/4176612.html ^_^肥子John
五、題外話——IE獨有的replaceNode和swapNode方法
IE5.5~11還提供了 el.replaceNode({HTMLElement} otherEl) 和 el.swapNode(HTMLElement} otherEl) 兩個方法, el.replaceNode({HTMLElement} otherEl) 作用是將el替換為otherEl并將el作為函數返回值, 此時el已經脫離了DOM樹; el.swapNode(HTMLElement} otherEl) 作用是交換el和otherEl在樹層級結構中的位置,兩者均在DOM樹中。 注意:這兩個方法均為IE獨有的。
文章列表