Conservare lo stato durante le mutazioni del DOM con moveBefore()

Siamo lieti di annunciare la nuova API DOM moveBefore(), disponibile nella versione 133 di Chrome, che semplifica lo spostamento degli elementi nel DOM senza perdere lo stato. Continua a leggere per scoprire come utilizzarlo nei tuoi progetti.

Perdita dello stato durante le mutazioni del DOM

Utilizzi l'API appendChild() per inserire nuovi elementi nel DOM? Lo fanno in molti, ma hai mai provato a chiamarla, o insertBefore() o qualsiasi altra API di inserimento, con un elemento già presente nel DOM? In questo caso, potresti non aver notato che questa operazione funziona silenziosamente rimuovendo prima l'elemento dal vecchio elemento principale e reinserendolo in quello nuovo. Questo perché il Document Object Model ha avuto solo le primitive remove e insert dalla prima bozza dello standard DOM introdotta nel 1998. Ogni volta che pensi di "spostare" qualcosa nel DOM da un punto all'altro, in realtà lo stai rimuovendo e inserendo sotto il cofano.

Il fatto che una "spostamento" sia in realtà un "rimozione e inserimento" di solito non ha alcun impatto sull'esperienza utente. Ad esempio, quando "sposti" un <p> nel DOM, queste due operazioni non hanno effetti collaterali negativi, ma quando sposti nodi complessi che contengono stati significativi, come elementi <iframe>, elementi a schermo intero, animazioni CSS e così via, l'operazione di "rimozione" implicita reimposta tutti i tipi di stato.

Ciò può avere effetti collaterali sorprendentemente disgregatori

Puoi vedere il tipo di stato che viene reimpostato nel nostro sito web demo che preserva lo stato provando a eseguire movimenti nella struttura DOM. L'esempio seguente mostra le animazioni CSS e il ripristino dello stato <iframe> quando gli elementi vengono spostati da un contenitore principale a un altro.

Questa limitazione può rendere difficile o addirittura impossibile la creazione di esperienze utente dinamiche. Gli utenti si sentono frustrati e confusi quando lo stato dell'applicazione viene reimpostato in modo misterioso e gli autori di framework JavaScript ne subiscono le conseguenze, trascorrendo innumerevoli ore a ristrutturare il codice frontend per risolvere il problema, creando librerie complesse come MorphDOM o gestendo segnalazioni di bug che evidenziano problemi che non riescono a risolvere.

La nuova API moveBefore()

Abbiamo deciso di risolvere il problema aggiungendo una nuova operazione primitiva al DOM. È chiamata in modo appropriato "move" ed è esposta agli sviluppatori tramite la nuova API DOM moveBefore().

moveBefore() accetta gli stessi argomenti di insertBefore(), ma anziché rimuovere e reinserire i nodi quando sono già collegati al DOM, questa nuova API sposta atomicamente il nodo target nel nuovo nodo principale senza reimpostare la maggior parte degli stati. In questo modo, gli sviluppatori JavaScript possono finalmente creare esperienze dinamiche con animazioni mobili, iframe, elementi a schermo intero e altro ancora. Puoi provare questa funzionalità attivando il flag sperimentale chrome://flags/#atomic-move e visitando il nostro sito demo oppure utilizzando la versione 133 di Chrome dopo il rilascio del 4 febbraio 2025.

Ecco alcuni esempi di comportamenti che questa nuova primitiva consentirà agli autori di JavaScript di ottenere:

  • Mantieni lo stato di riproduzione di un video mentre un utente naviga su un sito web (indipendentemente dal fatto che il video sia fornito da un elemento <video> o <iframe>).
  • Mantieni attivo il focus di un campo di immissione dell'utente quando viene spostato nel DOM.
  • Consenti il completamento delle animazioni senza problemi quando vengono aggiunti o rimossi nuovi contenuti dal DOM.
  • Algoritmi di morphing con una maggiore fedeltà per la riconciliazione dei DOM esistenti con i nuovi contenuti.
  • Mantieni aperte le finestre di dialogo modali, i popup e gli elementi a schermo intero.

Ci stiamo adoperando per introdurre questa API nella piattaforma web con altri browser e siamo entusiasti di renderla presto disponibile per gli sviluppatori, soddisfacendo anni di richieste degli sviluppatori e colmando una lacuna significativa nella piattaforma web.


Come sempre, facci sapere cosa ne pensi tramite Twitter o nei commenti di seguito e invia i bug all'indirizzo crbug.com/new.