Interface persistente da camada superior

Recursos da Web: moveBefore()

Ao mover um elemento <dialog>, popover ou de tela cheia aberto no DOM usando métodos tradicionais, como appendChild() ou insertBefore(), o navegador remove implicitamente o elemento do DOM e o insere novamente. Essa remoção redefine o estado, fazendo com que modais abertos, popovers e elementos em tela cheia sejam fechados abruptamente.

Para redefinir os elementos da camada superior sem interromper a experiência do usuário ou fechá-los, use a API atômica moveBefore().

Como redefinir o elemento pai de elementos de camada superior abertos

moveBefore() usa dois argumentos: o nó a ser movido e um nó de referência para inserir antes (ou null para anexar ao final do novo pai).

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);

Estratégias de fallback

Como moveBefore() é um aprimoramento progressivo, você PRECISA usar a detecção de recursos antes de chamá-lo. Para navegadores mais antigos, você terá que usar a mudança de elemento pai tradicional.

OBRIGATÓRIO: para elementos <dialog> em navegadores incompatíveis, o movimento tradicional vai fechar a caixa de diálogo. Se você quiser que ele permaneça aberto, reabra-o manualmente após a mudança.

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();
  }
}