Lorsque vous déplacez un élément <dialog>, popover ou plein écran ouvert dans le DOM à l'aide de méthodes traditionnelles telles que appendChild() ou insertBefore(), le navigateur supprime implicitement l'élément du DOM et le réinsère. Cette suppression réinitialise l'état, ce qui entraîne la fermeture brutale des fenêtres modales, des popovers et des éléments en plein écran ouverts.
Pour reparenter des éléments de la couche supérieure sans interrompre l'expérience utilisateur ni les fermer, utilisez plutôt l'API atomique moveBefore().
Reparentage des éléments de la couche supérieure ouverts
moveBefore() accepte deux arguments : le nœud à déplacer et un nœud de référence à insérer avant (ou null à ajouter à la fin du nouveau parent).
const newParent = document.getElementById('new-container');
const dialogElement = document.getElementById('my-dialog');
// MANDATORY: Use moveBefore to ensure the <dialog> or popover stays open.
// Passing null appends it to the end of newParent.
newParent.moveBefore(dialogElement, null);
Stratégies de remplacement
Étant donné que moveBefore() est une amélioration progressive, vous DEVEZ utiliser la détection de fonctionnalités avant de l'appeler. Pour les navigateurs plus anciens, vous devrez utiliser le reparentage traditionnel.
OBLIGATOIRE : Pour les éléments <dialog> dans les navigateurs non compatibles, le déplacement traditionnel ferme la boîte de dialogue. Si vous souhaitez qu'il reste ouvert, vous devez le rouvrir manuellement après le déplacement.
const targetParent = document.getElementById('target-container');
const popoverOrDialog = document.getElementById('my-top-layer-element');
// Check if moveBefore is supported
if ('moveBefore' in Element.prototype) {
targetParent.moveBefore(popoverOrDialog, null);
} else {
// Fallback: traditional move.
// Note: This WILL close <dialog>, popover, and fullscreen elements.
const wasOpen = popoverOrDialog.hasAttribute('open') || popoverOrDialog.matches(':popover-open');
targetParent.insertBefore(popoverOrDialog, null);
// Manually restore state if possible
if (wasOpen && typeof popoverOrDialog.showModal === 'function') {
popoverOrDialog.showModal();
} else if (wasOpen && typeof popoverOrDialog.showPopover === 'function') {
popoverOrDialog.showPopover();
}
}