Copying and Moving Nodes

cloneNode(true) copies a subtree, cloneNode() just the node. Copies lose addEventListener() listeners and non-clonable shadow roots. For another document's nodes, such as an iframe's, document.importNode(node, true) copies and document.adoptNode(node) moves.

Moving with append() or insertBefore() is really remove, then insert: iframes reload, CSS animations restart, and focus, open popovers and modal dialogs are lost. moveBefore(node, reference) moves atomically and keeps that state, within one connected document. It ships in Chrome 1 and Edge 133 and Firefox 144 555 , not yet Safari 10 , so fall back to insertBefore().

append() drops focus; moveBefore() keeps itHTMLLive
<div style="display:flex;gap:8px"><div id="a"><input id="field"></div><div id="b"></div></div>
<pre id="out" style="margin:0"></pre>
<script>
  const [a, b, field] = ['#a', '#b', '#field'].map((s) => document.querySelector(s));
  const focused = () => document.activeElement === field;
  field.focus({ preventScroll: true });
  b.append(field);
  const log = [`append():     still focused? ${focused()}`];
  field.focus({ preventScroll: true });
  if ('moveBefore' in a) a.moveBefore(field, null); else a.insertBefore(field, null);
  log.push(`moveBefore(): still focused? ${focused()}`);
  document.querySelector('#out').textContent = log.join('\n');
</script>
Browser output of Listing 8.26
Browser output of 26

Chrome's launch post names framework authors as the main audience, for reordering keyed lists (Virtual DOM and Signals).