Temos o prazer de anunciar a nova API DOM moveBefore()
, disponível na versão 133 do Chrome, que facilita a movimentação de elementos no DOM sem perder o estado. Continue lendo para descobrir como usá-lo nos seus projetos.
Perda de estado durante mutações do DOM
Você usa a API appendChild()
para inserir novos elementos no DOM? Muitas, mas você já tentou chamar esse método ou insertBefore()
ou qualquer outra API de inserção com um elemento que já está no DOM? Se sim, talvez você não tenha percebido que isso funciona primeiro removendo o elemento do elemento pai antigo e inserindo-o novamente no novo. Isso ocorre porque o modelo de objeto do documento só tinha as primitivas de remoção e inserção desde que o primeiro rascunho do DOM Standard foi introduzido em 1998. Sempre que você pensa que está "movendo" algo no DOM de um lugar para outro, na verdade você está removendo e inserindo.
O fato de uma "movimentação" ser realmente uma "remoção e inserção" geralmente não afeta a experiência do usuário. Por exemplo, ao "mover" um <p>
no DOM, essas duas operações não têm efeitos colaterais, mas, ao mover nós complexos que contêm estados significativos, como elementos <iframe>
, elementos em tela cheia, animações CSS e assim por diante, a operação de "remoção" implícita redefine todos os tipos de estado.
Isso pode ter efeitos colaterais surpreendentes.
Você pode conferir o tipo de estado que é redefinido no site de demonstração de preservação de estado testando movimentos na árvore DOM. O exemplo a seguir mostra animações CSS e a redefinição do estado <iframe>
ao mover elementos de um contêiner pai para outro.
Essa limitação pode dificultar ou até impossibilitar a criação de experiências dinâmicas para os usuários. Os usuários ficam frustrados e confusos quando o estado do aplicativo é redefinido misteriosamente, e os autores de frameworks JavaScript sofrem com isso, passando horas e horas reprojetando o código do front-end para resolver esse problema, criando bibliotecas complexas, como o MorphDOM, ou respondendo a relatórios de bugs que destacam problemas que não podem ser corrigidos.
A nova API moveBefore()
Para corrigir esse problema, adicionamos uma nova operação primitiva ao DOM. Ela é chamada de primitiva "move" e é exposta aos desenvolvedores pela nova API DOM moveBefore()
.
moveBefore()
usa os mesmos argumentos que insertBefore()
, mas, em vez de remover e reinserir nós quando eles já estão anexados ao DOM, essa nova API move de forma atômica o nó de destino para o novo pai sem redefinir a maioria dos estados. Isso permite que os desenvolvedores de JavaScript criem experiências dinâmicas com animações móveis, iframes, elementos em tela cheia e muito mais. Para testar isso, ative a flag experimental chrome://flags/#atomic-move
e acesse nosso site de demonstração ou use a versão 133 do Chrome após o lançamento em 4 de fevereiro de 2025.
Confira alguns exemplos de comportamentos que essa nova primitiva vai permitir que os autores de JavaScript alcancem:
- Preservar o estado de reprodução de um vídeo enquanto o usuário navega por um site (seja por um elemento
<video>
ou<iframe>
). - Preservar o foco de um campo de entrada do usuário conforme ele é movido no DOM.
- Permita que as animações terminem sem problemas à medida que o novo conteúdo é adicionado ou removido do DOM.
- Algoritmos de transformação de maior fidelidade para reconciliar DOMs existentes com novo conteúdo.
- Mantenha caixas de diálogo modais, pop-ups e elementos em tela cheia abertos.
Estamos trabalhando para introduzir essa API na plataforma da Web com outros navegadores e estamos animados para disponibilizar aos desenvolvedores em breve, atendendo a anos de solicitações e preenchendo uma lacuna significativa na plataforma da Web.
Como sempre, deixe sua opinião no Twitter ou nos comentários abaixo e envie bugs para crbug.com/new.