Inspect the fixed example
Build two list items inside a fragment, retain the first node reference, then append the fragment to notes.
<style>html{font-size:16px}body{margin:12px;font:1rem/1.5 system-ui,sans-serif;color:#17332d;background:#fff}p{overflow-wrap:anywhere}output{display:block;margin-block:12px;overflow-wrap:anywhere;white-space:pre-wrap}button,input{font:inherit;max-width:100%;box-sizing:border-box}button{margin:4px;padding:8px}label{display:block;margin-block:8px}button:focus-visible,input:focus-visible{outline:3px solid #23715d;outline-offset:2px}ul{padding-inline-start:24px}li{overflow-wrap:anywhere}.highlight{border:2px solid green}</style>
<ul id="notes"></ul><output id="result"></output>
<script>const fragment=document.createDocumentFragment();for(const text of ['Source','Preview']){const item=document.createElement('li');item.textContent=text;fragment.append(item);}const first=fragment.firstChild;const notes=document.querySelector('#notes');notes.append(fragment);
const result={fragmentChildren:fragment.childNodes.length,listChildren:notes.children.length,sameNode:first===notes.firstChild};
document.querySelector('#result').textContent=JSON.stringify(result);
console.log(JSON.stringify(result));
</script>{"fragmentChildren":0,"listChildren":2,"sameNode":true}| Inspection | Supplied input or action | Result |
|---|---|---|
| Fragment after append | childNodes.length | 0 |
| Destination list | children.length | 2 |
| First node identity | first===notes.firstChild | true |
Follow the native mechanism
Fragment insertion moves its children into the destination. The fragment itself is not inserted as a wrapper; it is empty afterward. The first item keeps its identity and now has notes as its parent. This fixture makes no speed or rendering-performance claim.
Compare the material alternative
Appending the same emptied fragment to another list does not copy the first list. The second list receives zero items.
<style>html{font-size:16px}body{margin:12px;font:1rem/1.5 system-ui,sans-serif;color:#17332d;background:#fff}p{overflow-wrap:anywhere}output{display:block;margin-block:12px;overflow-wrap:anywhere;white-space:pre-wrap}button,input{font:inherit;max-width:100%;box-sizing:border-box}button{margin:4px;padding:8px}label{display:block;margin-block:8px}button:focus-visible,input:focus-visible{outline:3px solid #23715d;outline-offset:2px}ul{padding-inline-start:24px}li{overflow-wrap:anywhere}.highlight{border:2px solid green}</style>
<ul id="first"></ul><ul id="second"></ul><output id="result"></output>
<script>const fragment=document.createDocumentFragment();for(const text of ['Source','Preview']){const item=document.createElement('li');item.textContent=text;fragment.append(item);}document.querySelector('#first').append(fragment);document.querySelector('#second').append(fragment);
const result={first:document.querySelector('#first').children.length,second:document.querySelector('#second').children.length,fragment:fragment.childNodes.length};
document.querySelector('#result').textContent=JSON.stringify(result);
console.log(JSON.stringify(result));
</script>{"first":2,"second":0,"fragment":0}Work the boundary
How can a second list receive copied items while retaining the first list’s node identities?
Show the worked answer
Clone the populated fragment before consuming it, then append the two separate fragments. Each list gets two items; their first nodes are distinct.
<style>html{font-size:16px}body{margin:12px;font:1rem/1.5 system-ui,sans-serif;color:#17332d;background:#fff}p{overflow-wrap:anywhere}output{display:block;margin-block:12px;overflow-wrap:anywhere;white-space:pre-wrap}button,input{font:inherit;max-width:100%;box-sizing:border-box}button{margin:4px;padding:8px}label{display:block;margin-block:8px}button:focus-visible,input:focus-visible{outline:3px solid #23715d;outline-offset:2px}ul{padding-inline-start:24px}li{overflow-wrap:anywhere}.highlight{border:2px solid green}</style>
<ul id="first"></ul><ul id="second"></ul><output id="result"></output>
<script>const fragment=document.createDocumentFragment();for(const text of ['Source','Preview']){const item=document.createElement('li');item.textContent=text;fragment.append(item);}const copy=fragment.cloneNode(true);const first=document.querySelector('#first'),second=document.querySelector('#second');first.append(fragment);second.append(copy);
const result={first:first.children.length,second:second.children.length,sameNode:first.firstChild===second.firstChild,originalFragment:fragment.childNodes.length,copiedFragment:copy.childNodes.length};
document.querySelector('#result').textContent=JSON.stringify(result);
console.log(JSON.stringify(result));
</script>{"first":2,"second":2,"sameNode":false,"originalFragment":0,"copiedFragment":0}