Skip to content
Astera Technology

Append a fragment and watch its children move

Insert a DocumentFragment and follow where its child nodes move.

Download complete case notes and answer keys ↓

Inspect the fixed example

Build two list items inside a fragment, retain the first node reference, then append the fragment to notes.

Complete body and fixed script
<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>
Exact console output
{"fragmentChildren":0,"listChildren":2,"sameNode":true}
Inputs and native results
InspectionSupplied input or actionResult
Fragment after appendchildNodes.length0
Destination listchildren.length2
First node identityfirst===notes.firstChildtrue

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.

Fresh counterexample source
<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>
Counterexample output
{"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.

Fresh boundary source
<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>
Boundary output
{"first":2,"second":2,"sameNode":false,"originalFragment":0,"copiedFragment":0}

Original example files