做者:
John Resig
最近我正在研究
DOM DocumentFragments ,在JavaScript裏,我看看用他們能作出什麼東西。
粗略的說,一個
DocumentFragment 是一個輕量級的容器,能夠持有DOM節點。它是DOM1規範的一部分而且在現代全部瀏覽器中被普遍支持(
IE在版本6中加入了它)。
在研讀它們的時候我遇到一個頗有趣的點,規範中說:
另外,各個操做--好比給另外一個節點插入子節點--可能拿DocumentFragment對象做爲參數;這會致使DocumentFragment的全部子節點被移植爲這個節點的子列表。
這意味着,若是你有一羣節點而且附加他們到一個片斷,而後你就能夠簡單的把這個片斷附加給document(這能達到一樣的效果,就像你單獨的去操做每個元素)。我當即感受到這兒可能會存在性能提高。我作了進一步的調查而且注意到DocumentFragments也支持cloneNode方法。這爲你進行高效的DOM節點插入操做提供了全部功能。
讓咱們來考慮你有一堆節點並要把他們插入到DOM中的情形(在DEMO中是12個節點--8個在最頂層--對着一個亂糟糟的div)。
var elems = [
document_createElement_x("hr"),
text( document_createElement_x("b"), "Links:" ),
document_createTextNode(" "),
text( document_createElement_x("a"), "Link A" ),
document_createTextNode(" | "),
text( document_createElement_x("a"), "Link B" ),
document_createTextNode(" | "),
text( document_createElement_x("a"), "Link C" )
];
function text(node, txt){
node.a( document_createTextNode(txt) );
return node;
}
通常的附加
若是咱們想附加一些借點到document,咱們可能會按照常規作法:遍歷節點並分別複製他們(而後咱們能夠繼續把他們附加給整個文檔)。
var div = document.getElementsByTagName_r("div");
for ( var i = 0; i < div.length; i++ ) {
for ( var e = 0; e < elems.length; e++ ) {
div[i].a( elems[e].cloneNode(true) );
}
}
DocumentFragment 附加
然而,當咱們把DocumentFragments帶入視野之後咱們當即能看到一個不一樣的結構。開始,咱們附加咱們的全部的節點到片斷自己(由createDocumentFragment方法建立)。
可是當真正往document裏
執行插入節點的時候有趣的事情發生了:對全部節點咱們只須要調用一次a和cloneNode方法。
var div = document.getElementsByTagName_r("div");
var fragment = document_createDocumentFragment();
for ( var e = 0; e < elems.length; e++ ) {
fragment.a( elems[e] );
}
for ( var i = 0; i < div.length; i++ ) {
div[i].a( fragment.cloneNode(true) );
}
設置一些時間戳咱們能夠看到咱們的結果有豐厚的回報:
Browser |
Normal (ms) |
Fragment (ms) |
Firefox 3.0.1 |
90 |
47 |
Safari 3.1.2 |
156 |
44 |
Opera 9.51 |
208 |
95 |
IE 6 |
401 |
140 |
IE 7 |
230 |
61 |
IE 8b1 |
120 |
40 |
結果代表:在很大程度上被人們忽略的一個方法,對於你的DOM操做可以提供很大的(2-3X)性能提高。