天天看點

解密jQuery核心 DOM操作的核心buildFragment文檔碎片是什麼createDocumentFragment有什麼作用DocumentFragment類型createElement與createDocumentFragmentbuildFragment

<a href="http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-B63ED1A3">http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-B63ED1A3</a>

參考标準的描述,DocumentFragment是一個輕量級的文檔對象,能夠提取部分文檔的樹或建立一個新的文檔片段

換句話說有文檔緩存的作用

<a></a>

多次使用節點方法(如:appendChild)繪制頁面,每次都要重新整理頁面一次。效率也就大打折扣了,而使用document_createDocumentFragment()建立一個文檔碎片,把所有的新結點附加在其上,然後把文檔碎片的内容一次性添加到document中,這也就隻需要一次頁面重新整理就可。

在所有節點類型中,隻有DocumentFragment在文檔中沒有對應的标記。DOM規定文檔片段(documentfragment)是一種”輕量級“的文檔,可以包含和控制節點,但不會像完整的文檔那樣占用額外資源。DocumentFragment節點具有下列特征:

nodeType的值為11

nodeName的值為“#document-fragment”

nodeValue的值為null

parentNode的值為null

子節點可以是Element、ProcessingInstruction、Comment、Text、CDATASection或EntityReference

雖然不能把文檔片段直接添加到文檔中,但可以将它作為一個“倉庫”來使用,即可以在裡面儲存将來可能會添加到文檔中的節點。要建立文檔片段,可以使用document.createDocumentFragment()方法,如下所示:

文檔片段繼承了Node的所有方法,通常用于執行那些針對文檔的DOM操作。如果将文檔中的節點添加到文檔片段中,就會從文檔樹中再看到該節點。添加到文檔片段中的新節點同樣也不屬于文檔樹。可以通過appendChild()或insertBefore()将文檔片段中内容添加到文檔中。在将文檔片段作為參數傳遞給這兩個方法時,實際上隻會将文檔片段的所有子節點添加到相應的位置上;文檔片段本身永遠不會稱為文檔樹的一部分

<a href="http://www.w3cmm.com/dom/documentfragment.html">http://www.w3cmm.com/dom/documentfragment.html</a>

createElement是建立一個新的節點,createDocumentFragment是建立一個文檔片段

DocumentFragment 節點不屬于文檔樹,繼承的 parentNode 屬性總是 null。

不過它有一種特殊的行為,該行為使得它非常有用

可以用 Document.createDocumentFragment() 方法建立新的空 DocumentFragment 節點。

除此之外

createElement建立的元素可以使用innerHTML,createDocumentFragment建立的元素使用innerHTML并不能達到預期修改文檔内容的效果,隻是作為一個屬性而已。兩者的節點類型完全不同,并且createDocumentFragment建立的元素在文檔中沒有對應的标記,是以在頁面上隻能用js中通路到

createElement建立的元素可以重複操作,添加之後就算從文檔裡面移除依舊歸文檔所有,可以繼續操作,但是createDocumentFragment建立的元素是一次性的,添加之後再就不能操作了

大體了解了,我們看看jQuery對于節點操作的時候,加強版的文檔碎片buildFragment

我們知道用文檔碎片無非就是先建立

然後把所有需要處理的dom節點給appendChild進去

buildFragment對于文檔碎片的建立,可以看到被切分了2個部分

先看第一部分代碼

我們看一個參數,包含了 字元串,$對象

對應的buildFragment就需要針對傳入elems的分解可以有三部分,引入一個nodes緩存起來

将HTML代碼指派給一個DIV元素的innerHTML屬性,然後取DIV元素的子元素,即可得到轉換後的DOM元素、

建立了一個臨時的tmp元素(div),這樣調用innerHTML方法,用來儲存建立的節點的内容,fragment本身隻是起到一個容器的作用,這點我們要記住了

但是jQuery引入了一個wrapMap,一個反序列化表示

用來幹嘛的?

我們知道看jQuery建立元素類型可以是任意的,可以是以可以是是a,scrpit,tr,th,option等等

但是在并不是所有元素的的建立都是标準的,在不同浏覽器下還是有差別,比如表格

比如在table中插入一行一列

IE 6上失敗的原因就是IE 6認為tr标簽必須在tbody下面。也就是說,代碼寫成下面這樣,就所有浏覽器都OK了。

是以如果是jQuery插入一個tr标簽,就需要在内部做這樣的處理工作了

wrapMap就是用來做适配的

拼寫出來的規則就是

具體有多少類似的問題我們看看

解密jQuery核心 DOM操作的核心buildFragment文檔碎片是什麼createDocumentFragment有什麼作用DocumentFragment類型createElement與createDocumentFragmentbuildFragment

因為wrapMap容器打破了原來的排列組合是以tr節點位置需要重新定位

就那面這個tr,lastChild變成了table, 是以需要根據wrap[ 0 ]找到嵌套的層數

因為fragment現在還不确定是最終的,因為node可能還有其他的節點,是以

處理第一種情況,如果元素和目标元素是相同的

<a href="http://bugs.jquery.com/ticket/4087">http://bugs.jquery.com/ticket/4087</a>

周遊每一個元素放入到文檔碎片中

fragment.appendChild( elem )

還有種情況就是寫入的是scrpit标簽了,用的很少先跳過

最終傳回fragment

本文轉自艾倫 Aaron部落格園部落格,原文連結:http://www.cnblogs.com/aaronjs/p/3510768.html,如需轉載請自行聯系原作者

繼續閱讀