做者:
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)性能提高。