DocumentFragment теряет часть моего контента - PullRequest
3 голосов
/ 21 марта 2019

Итак, я просто пытаюсь переместить элемент с одного узла на другой.Я создаю фрагмент и затем добавляю к нему мои дочерние элементы.

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>

Я неправильно понимаю, как работают фрагменты?

Это странно работает над фрагментом ... Даже частично работает на моем компьютере, но становится странным.

enter image description here

enter image description here

Я думаю, что есть изменение между моментом, когда я печатаю свою переменную иЯ исследую это.

1 Ответ

1 голос
/ 21 марта 2019

Вы мутируете 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>
...