DOM-element verplaatsen zonder status te verliezen

Webfuncties: moveBefore()

Als je DOM-elementen opnieuw bovenliggend maakt met traditionele methoden zoals appendChild() of insertBefore(), verwijdert de browser het element impliciet uit de DOM en voegt het daarna in op de nieuwe locatie. Deze bewerking voor verwijderen en invoegen reset veel interne statussen, waardoor <iframe>-elementen opnieuw worden geladen, CSS-animaties opnieuw worden gestart en invoervelden de focus verliezen.

Gebruik de moveBefore() API om een element te verplaatsen terwijl de status behouden blijft. Met deze methode wordt een atomische verplaatsing uitgevoerd, waarbij de stappen voor verwijderen en invoegen volledig worden overgeslagen.

Een element met een status verplaatsen

Gebruik moveBefore() op dezelfde manier als insertBefore(). Hiervoor zijn 2 argumenten vereist: de node die moet worden verplaatst en een referentienode die ervoor moet worden ingevoegd (of null om aan het einde van de nieuwe bovenliggende node toe te voegen).

const newParent = document.getElementById('new-parent');
const elementWithState = document.getElementById('iframe-or-focused-input');

// MANDATORY: Use moveBefore to preserve state. 
// Passing null as the second argument appends the element to the end of newParent.
newParent.moveBefore(elementWithState, null);

Aangepaste elementen verplaatsen (webcomponenten)

Als je aangepaste elementen verplaatst met moveBefore(), worden de levenscyclusmethoden connectedCallback en disconnectedCallback niet geactiveerd.

Als je aangepaste element specifieke logica moet uitvoeren wanneer het wordt verplaatst, implementeer je de methode connectedMoveCallback() in de definitie van het aangepaste element.

class MyCustomElement extends HTMLElement {
  connectedCallback() {
    // Runs on initial insertion.
  }
  
  connectedMoveCallback() {
    // Runs when the element is moved via moveBefore().
    // Use this to update state that depends on the new DOM location.
  }
}

Reservestrategieën

Omdat moveBefore() een progressive enhancement is, MOET je functiedetectie gebruiken voordat je deze aanroept. Voor oudere browsers moet je terugvallen op traditionele insertBefore()- of appendChild()-bewerkingen.

const targetParent = document.getElementById('target-container');
const nodeToMove = document.getElementById('moving-element');

// Check if moveBefore is supported on the Element prototype
if ('moveBefore' in Element.prototype) {
  targetParent.moveBefore(nodeToMove, null);
} else {
  // Fallback: traditional move. 
  // Note: This WILL reset <iframe>, animation, and focus state in unsupported browsers.
  targetParent.insertBefore(nodeToMove, null);
}