1、前言 html
當須要新元素時咱們能夠經過 document.createElement 接口來建立一個全新的元素,也能夠經過克隆已有元素的方式來獲取一個新元素。而在部分瀏覽器中,經過複製來獲取新元素的效率比經過 document.createElement 方式的要高一些,具體的性能比較以下:node
2% in IE8, but no change in IE6 and IE7瀏覽器
Up to 5.5% in Firefox 3.5 and Safari 4app
6% in Opera (but no savings in Opera 10)函數
10% in Chrome 2 and 3% in Chrome 3性能
本篇將記錄元素克隆、和剪切的相關技術,以便往後查閱。測試
目錄一坨:spa
2、拷貝code
2. appendChild、insertBefore和replaceChild
5、題外話——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
5、題外話——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獨有的。