代码改变世界

理解 DocumentFragment

2017-09-02 10:24 龙恩0707 阅读(...) 评论(...) 编辑 收藏

理解 DocumentFragment

含义:创建文档片段,它继承了Node的所有方法,对DOM操作性能非常好。
创建文档片段 如下方法:

var frag = document.createDocumentFragment();

文档片段有三个node属性,nodeType, nodeName, nodeValue; 他们的值分别是 11, '#document-fragment', null, 文档片段节点没有父节点parentNode. 如下代码演示:

var frag = document.createDocumentFragment();
 console.log(frag.nodeType);  // 11
 console.log(frag.nodeValue); // null
 console.log(frag.nodeName);  // #document-fragment
 console.log(frag.parentNode); // null

它有什么作用呢?
我们经常使用js来操作DOM操作,比如向页面中插入元素,每次插入元素的时候,浏览器会发生重绘,都需要重新渲染页面,如果做大量的这样的操作,非常影响性能的,影响用户体验。
比如如下代码:

var ul = document.getElementById("ulId");
for (var i = 0; i < 30; i++) {
   var li = document.createElement('li');
   li.innerHTML = "aaa" + i;
   ul.appendChild(li)
 }

我们知道每一次插入都会引起重新渲染(计算元素的尺寸,显示内容等),会重新重绘页面,因此会影响性能的,我们最常见还有一种方法是将创建的元素写到一个字符串上,然后一次性写到innerHTML上,这种使用浏览器对innerHTML的解析比上面多次插入快很多,但是构造字符串灵活性比较差,很难符合创建各种各样的DOM元素。如下代码:

var ul = document.getElementById("ulId");
var ihtml = '';
for (var i = 0; i < 30; i++) {
  ihtml += '<li>'+i+'</li>';
}
ul.innerHTML = ihtml;

但是使用DocumentFragment,可以弥补上面两种方法的不足。
DocumentFragment是没有父节点的最小文档对象,常用于存储html和xml文档,它继承了Node,因此它有Node的所有属性和方法,完全可以操作Node那样操作DocumentFragment.

DocumentFragment文档片段是存在于内存中的,没有在DOM中,所以将子元素插入到文档片段中不会引起页面回流,因此使用DocumentFragment可以起到性能优化作用。
比如上面插入的代码可以改成如下:

<!DOCTYPE html>
 <html>
  <head>
    <meta charset="utf-8">
    <meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport">
    <meta content="yes" name="apple-mobile-web-app-capable">
    <meta content="black" name="apple-mobile-web-app-status-bar-style">
    <meta content="telephone=no" name="format-detection">
    <meta content="email=no" name="format-detection">
    <title>标题</title>
    <link rel="shortcut icon" href="/favicon.ico">
  </head>
  <body>
    <ul id="ulId"></ul>
    <script>
     var ul = document.getElementById("ulId");
     var frag = document.createDocumentFragment();
     var ihtml = '';
     for (var i = 0; i < 30; i++) {
       var li = document.createElement('li');
       li.innerHTML = "index: " + i;
       frag.appendChild(li);
     }
     ul.appendChild(frag);
    </script>
  </body>
</html>