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().
<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>
Chrome's launch post names framework authors as the main audience, for reordering keyed lists (Virtual DOM and Signals).