Zachowanie stanu podczas mutacji DOM za pomocą funkcji moveBefore()

Z przyjemnością informujemy, że w Chrome w wersji 133 dostępny jest nowy interfejs DOM API moveBefore(), który ułatwia przenoszenie elementów w DOM bez utraty stanu. Czytaj dalej, aby dowiedzieć się, jak możesz go używać w swoich projektach.

Utrata stanu podczas mutacji DOM

Czy do wstawiania nowych elementów do DOM używasz interfejsu API appendChild()? Wiele osób ma ten problem, ale czy kiedykolwiek próbowałeś wywołać go (lub insertBefore(), albo dowolnego innego interfejsu API do wstawiania) za pomocą elementu, który znajduje się już w DOM? W takim przypadku możesz nie wiedzieć, że ta funkcja działa po cichu, najpierw usuwając element ze starego elementu nadrzędnego, a następnie wstawiając go w nowym. Dzieje się tak, ponieważ od czasu wprowadzenia pierwszego projektu standardu DOM w 1998 r. model obiektowy dokumentu zawierał tylko prymitywne operacje usuwania i wklejania. Gdy wydaje Ci się, że coś „przesuwasz” w DOM z jednego miejsca do drugiego, tak naprawdę usuwasz i wstawiasz elementy.

Fakt, że „przesuwanie” jest w istocie „usuwaniem i wstawianiem”, zwykle nie ma wpływu na wrażenia użytkownika. Na przykład podczas „przemieszczania” elementu <p> w DOM-ie te dwie operacje nie mają żadnych zakłócających skutków ubocznych, ale podczas przemieszczania złożonych węzłów, które zawierają istotne stany, takich jak elementy <iframe>, elementy w trybie pełnoekranowym, animacje CSS itp., operacja domyślnego „usunięcia” powoduje zresetowanie wszystkich stanów.

Może to mieć zaskakująco niekorzystne skutki uboczne.

Aby zobaczyć, jaki stan jest resetowany w naszej witrynie demonstracyjnej z zachowaniem stanu, możesz poeksperymentować z przesunięciami w drzewie DOM. Ten przykład pokazuje animacje CSS i stan <iframe> resetowany podczas przenoszenia elementów z jednego kontenera nadrzędnego do drugiego.

To ograniczenie może utrudniać, a nawet uniemożliwiać tworzenie dynamicznych treści. Użytkownicy są sfrustrowani i zdezorientowani, gdy stan aplikacji jest tajemniczo resetowany, a twórcy frameworków JavaScript muszą poświęcić niezliczone godziny na przeprojektowanie kodu po stronie klienta, aby rozwiązać ten problem, tworząc złożone biblioteki, takie jak MorphDOM, lub zajmować się raportami o błędach, które wykazują problemy, których nie można rozwiązać.

Nowy interfejs API moveBefore()

Aby rozwiązać ten problem, dodaliśmy do DOM nową operację prymitywną. Jest to odpowiednio nazwany prymityw „move” i jest udostępniany deweloperom za pomocą nowego interfejsu DOM moveBefore()API.

Funkcja moveBefore() przyjmuje te same argumenty co funkcja insertBefore(), ale zamiast usuwania i ponownie wstawiania węzłów, gdy są one już dołączone do DOM, nowy interfejs API przenosi je w sposób automatyczny do nowego elementu nadrzędnego bez resetowania większości stanu. Dzięki temu deweloperzy JavaScripta mogą tworzyć dynamiczne treści z animowanymi elementami, ramkami iframe i elementami na pełnym ekranie. Możesz to sprawdzić samodzielnie, włączając flagę eksperymentalną chrome://flags/#atomic-move i otwierając naszą stronę demonstracyjną lub używając wersji 133 Chrome po jej wydaniu 4 lutego 2025 r.

Przykłady zachowań, które ten nowy element umożliwi autorom JavaScriptu:

  • Zachowanie stanu odtwarzania filmu podczas poruszania się użytkownika po witrynie (niezależnie od tego, czy film jest udostępniany z elementu <video> czy <iframe>).
  • Zachowywanie pola wprowadzania danych użytkownika w centrum uwagi podczas jego przenoszenia w DOM.
  • Dopuszczaj płynne zakończenie animacji podczas dodawania lub usuwania nowych treści z DOM.
  • Algorytmy tworzenia przejść o wyższej jakości do porównywania dotychczasowych DOM-ów z nowymi treściami.
  • Nie zamykaj okien modalnych, wyskakujących ani elementów pełnoekranowych.

Pracujemy nad wprowadzeniem tego interfejsu API na platformę internetową w innych przeglądarkach. Cieszymy się, że wkrótce udostępnimy go deweloperom, spełniając ich wieloletnie oczekiwania i zamykając ważną lukę w platformie internetowej.


Jak zawsze przekazuj nam swoje opinie na Twitterze lub w komentarzach poniżej oraz zgłaszaj błędy na stronie crbug.com/new.