DocumentFragment丢失了我的部分内容

3

我基本上只是尝试将元素从一个节点移动到另一个节点。 我创建了一个片段,然后将我的子元素附加到它上面。

const fragment = document.createDocumentFragment();
let sortedElements = [...document.querySelectorAll('.product')].sort((a,b) => b.dataset.blockSize - a.dataset.blockSize ); //Select elements
sortedElements.forEach((e) => {
    console.log(e) //My 4 children displayed
    fragment.appendChild(e)
});
console.log(fragment.children); //Only Two children in it

fragment.childNodes.forEach((el) => {
    document.querySelector("#appendThere").appendChild(el);
})
<div class="product" data-object-size="4">Product 1</div>
<div class="product" data-object-size="2">Product 2</div>
<div class="product" data-object-size="1">Product 3</div>
<div class="product" data-object-size="1">Product 4</div>

<div id="appendThere"></div>

我是否误解了片段的工作原理?

它在代码片段上奇怪地运行...甚至在我的电脑上部分运行,但事情变得越来越奇怪。

在这里输入图片描述

在这里输入图片描述

我认为在打印变量和探索变量之间有一个变化。


我无法重现它 - 你能添加一些可以重现问题的内容吗?仅凭猜测,是否有一些带有"class = product"类的项目是其他带有"class = product"类的元素的子元素? - VLAZ
@benvc 我已经尝试编辑了,但正如你所说的那样,它确实很奇怪。 - Baldráni
@benvc 嗯,我已经更改了它,这与HTML无关,很可能是由于Fragment内存使用的方式所致。 - Baldráni
1
@VLAZ,这里有一个带有我的错误的工作代码片段。 - Baldráni
1
@Baldráni 好的,很奇怪 - 控制台日志确实显示了4,但是在添加时,你只得到了每隔一个项目。 - VLAZ
请查看此 Stack Overflow 答案 -> https://stackoverflow.com/a/31332027/10921798 - d-h-e
1个回答

1
你正在遍历fragment.childNodes时对其进行修改,这会导致意外的行为。你只需要添加fragment而不是添加它的每个子元素。
例如(修复了元素数据属性以对应于你示例中的排序js):

const fragment = document.createDocumentFragment();
const sorted = [...document.querySelectorAll('.product')].sort((a,b) => {
  return b.dataset.blockSize - a.dataset.blockSize;
});

sorted.forEach((elem) => {
  fragment.appendChild(elem);
});

document.querySelector('#destination').appendChild(fragment);
<div class="product" data-block-size="3">Product 2</div>
<div class="product" data-block-size="1">Product 3</div>
<div class="product" data-block-size="4">Product 1</div>
<div class="product" data-block-size="1">Product 4</div>
<div id="destination"></div>

或者,不使用文档片段(如果您只处理有限数量的元素,则可能没有太大的性能差异)。

const destination = document.querySelector('#destination');
const sorted = [...document.querySelectorAll('.product')].sort((a,b) => {
  return b.dataset.blockSize - a.dataset.blockSize;
});

sorted.forEach((elem) => {
  destination.appendChild(elem);
});
<div class="product" data-block-size="3">Product 2</div>
<div class="product" data-block-size="1">Product 3</div>
<div class="product" data-block-size="4">Product 1</div>
<div class="product" data-block-size="1">Product 4</div>
<div id="destination"></div>


很遗憾我们不能这样做,但可以使用“reduce”或类似的进程来处理!感谢提供链接。 - Baldráni
@Baldráni - 如果您无法附加文档片段,则可能根本不需要使用文档片段。为什么不直接将元素附加到目标上,跳过整个片段步骤呢?在答案中添加了第二个示例以说明。 - benvc
因为我没有将元素附加到相同的元素上 :) - Baldráni
@Baldráni - 如果是这样的话,除非您要附加元素组,否则绝对不需要使用文档片段,您可以使用多个文档片段来完成。 - benvc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接