【问题标题】:Document fragment vs `div` container文档片段与 `div` 容器
【发布时间】:2016-11-05 22:53:06
【问题描述】:

我搜索了 stackoverflow 问题,发现关于同一主题的问题很少,但没有一个问题能提供我正在寻找的广泛答案。大多数答案都集中在性能上,但我也在寻找其他差异。基本上,this one 简洁地总结了这个问题:

如果我在变量中创建一个元素(例如 a)但不要 将它附加到 DOM,添加元素(div、表格等)和东西 在完成所有工作之后(循环、验证、样式 元素),那个元素是附加的,和片段一样吗?

我决定再试一次,看看有没有人能给出好的答案。

那么,我为什么要使用这个:

var fragment = document.createDocumentFragment();
var divContainer = document.createElement("div");
var divHeader = document.createElement("div");
divContainer.appendChild( divHeader );
fragment.appendChild( divContainer );
document.getElementById("someElement").appendChild( fragment.cloneNode(true) );

而不是这个:

var divContainer = document.createElement("div");
var divHeader = document.createElement("div");
divContainer.appendChild( divHeader );
document.getElementById("someElement").appendChild( divContainer );

【问题讨论】:

  • @JamesThorpe,我用Most answers are focused around performance, but I'm looking for other differences as well.更新了我的问题
  • 不一样,因为 DOM 中不存在该片段,或者我错过了问题
  • 问题是什么?你在寻找什么差异?未添加到 DOM 的元素只是内存中的变量,不会被浏览器渲染。你还想知道什么?
  • 我认为你应该发布你自己的问题关于你有疑问。
  • @CharlieH,更新了问题

标签: javascript html dom


【解决方案1】:

这两种方法在很大程度上是相同的,因为它们都可以用于存储元素而无需立即修改 DOM。不过有一些问题。

区别:

  • div 有原型链HTMLDivElement - HTMLElement - Element - Node - EventTarget,而document-fragment 有DocumentFragment - Node - EventTarget。这意味着div 有更多可用的方法和属性(如innerHTML)。
  • 将div 附加到DOM 时,会插入整个元素,变量仍然引用该元素。附加 document-fragment 会插入其所有内容,让变量引用一个空片段。

使用document-fragment:

var fragment = document.createDocumentFragment();
var div1 = document.createElement('div');
var div2 = document.createElement('div');
var div3 = document.createElement('div');

fragment.appendChild(div1);
fragment.appendChild(div2);
div2.appendChild(div3);              //fragment now contains the sub-tree

document.body.appendChild(fragment); //fragment is now an empty document-fragment, and is not in the DOM.

结果:

<body>
    <div></div>       <!--div1-->
    <div>             <!--div2-->
         <div></div>  <!--div3-->
    </div>
</body>

使用div:

var container = document.createElement('div');
var div1 = document.createElement('div');
var div2 = document.createElement('div');
var div3 = document.createElement('div');

container.appendChild(div1);
container.appendChild(div2);
div2.appendChild(div3);               //container is now a div with the sub-tree inside.

document.body.appendChild(container); //container is still the div with the sub-tree, but is now in the DOM.

结果:

<body>
    <div>                 <!--container-->
        <div></div>       <!--div1-->
        <div>             <!--div2-->
             <div></div>  <!--div3-->
        </div>
    </div>
</body>

简而言之:

  • 如果您只想插入一个元素(其他元素在里面),请使用element。
  • 如果您想使用 innerHTML 解析文本格式的 html,请使用 element。
  • 如果要插入多个相邻元素,请使用document-fragment。

【讨论】:

  • 我认为问题更多是关于速度。这适用于动态创建需要列表包装​​器的列表之类的事情。如果你只是说var ul = document.createElement('ul');for (i = 0; i &lt; 10000; i++) { ul.appendChild(document.createElement('li')) }document.body.appendChild(ul),那实际上应该比创建frag,将li附加到frag,将frag附加到ul,然后最后将ul附加到body。
  • @cowbert,真的。那是因为您只附加到 DOM 一次。当&lt;ul&gt; 已经存在于 DOM 中时,情况会有所不同。
  • 完美。谢谢你的回答。
【解决方案2】:

您可能正在尝试比较 DocumentFragments 插入方法与使用 innerHTML 生成 DOM 树。

首先让我们从definition开始:

DocumentFragment 是没有父级的最小文档对象。它 用作文档的轻量级版本,用于存储格式良好或 可能不是格式良好的 XML 片段。

所以在使用 DocumentFragments 时确实存在结构上的差异:在附加 DOM 元素之前,我们可以访问不同的 DOM 方法。

此外,DocumentFragments 是 much faster,而不是在循环末尾附加一个带有 div.innerHTML = '...' 的大 HTML 文本,因为 DOM 结构不应动态生成,它已经可以从 Fragment 获得。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-18
    • 1970-01-01
    • 2017-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多