Mempertahankan status selama mutasi DOM dengan moveBefore()

Dengan senang hati kami mengumumkan moveBefore() DOM API baru, yang tersedia di Chrome versi 133, yang mempermudah pemindahan elemen di DOM tanpa kehilangan status. Baca terus untuk mengetahui cara menggunakannya dalam project Anda.

Kehilangan status selama mutasi DOM

Apakah Anda menggunakan appendChild() API untuk menyisipkan elemen baru ke dalam DOM? Begitu juga dengan banyak orang, tetapi pernahkah Anda mencoba memanggilnya—atau insertBefore(), atau API penyisipan lainnya—dengan elemen yang sudah ada di DOM? Jika demikian, Anda mungkin tidak menyadari bahwa hal ini berfungsi dengan baik dengan menghapus elemen dari induk lamanya terlebih dahulu, lalu menyisipkannya kembali ke induk yang baru. Hal ini karena Document Object Model hanya memiliki primitif penghapusan dan penyisipan sejak draf Standar DOM pertama diperkenalkan pada tahun 1998. Setiap kali Anda merasa "memindahkan" sesuatu di DOM dari satu tempat ke tempat lain, Anda sebenarnya menghapus dan menyisipkan di balik layar.

Fakta bahwa "pindahkan" sebenarnya adalah "hapus dan masukkan" biasanya tidak memengaruhi pengalaman pengguna. Misalnya, saat "memindahkan" <p> di DOM, kedua operasi ini tidak memiliki efek samping yang mengganggu, tetapi saat memindahkan node kompleks yang menyimpan status yang signifikan—seperti elemen <iframe>, elemen dalam layar penuh, animasi CSS, dan sebagainya—operasi "penghapusan" implisit akan mereset semua jenis status.

Hal ini dapat memiliki efek samping yang mengganggu

Anda dapat melihat jenis status yang direset di situs demo preservasi status dengan mencoba berbagai gerakan di hierarki DOM. Contoh berikut menunjukkan animasi CSS dan reset status <iframe> saat memindahkan elemen dari satu penampung induk ke penampung induk lainnya.

Batasan ini dapat mempersulit atau bahkan membuat tidak mungkin untuk membangun pengalaman pengguna yang dinamis. Pengguna merasa frustrasi dan bingung saat status aplikasi direset secara misterius, dan penulis framework JavaScript menanggung beban ini dengan menghabiskan waktu berjam-jam untuk mendesain ulang kode frontend mereka terkait masalah ini, menulis library kompleks seperti MorphDOM, atau dengan menerima laporan bug yang menyoroti masalah yang tidak dapat mereka perbaiki.

moveBefore() API baru

Kami berupaya memperbaiki masalah ini dengan menambahkan operasi primitif baru ke DOM. Ini disebut dengan tepat sebagai primitif "pindahkan", dan ditampilkan kepada developer melalui moveBefore() DOM API baru.

moveBefore() menggunakan argumen yang sama dengan insertBefore(), tetapi bukan menghapus dan menyisipkan kembali node saat sudah dilampirkan ke DOM, API baru ini secara otomatis memindahkan node target ke induk baru tanpa mereset sebagian besar status. Hal ini akhirnya memungkinkan developer JavaScript membuat pengalaman dinamis dengan animasi yang dapat dipindahkan, iframe, elemen layar penuh, dan lainnya. Anda dapat mencobanya sendiri dengan mengaktifkan tanda eksperimental chrome://flags/#atomic-move dan mengunjungi situs demo kami, atau dengan menggunakan Chrome versi 133 setelah dirilis pada 4 Februari 2025.

Contoh perilaku yang dapat dicapai oleh penulis JavaScript dengan primitif baru ini adalah:

  • Mempertahankan status pemutaran video saat pengguna menjelajahi situs (baik video disediakan dari elemen <video> atau <iframe>).
  • Mempertahankan fokus kolom input pengguna saat dipindahkan di DOM.
  • Mengizinkan animasi selesai dengan lancar saat konten baru ditambahkan atau dihapus dari DOM.
  • Algoritme morphing fidelitas yang lebih tinggi untuk merekonsiliasi DOM yang ada dengan konten baru.
  • Tetap buka dialog modal, popover, dan elemen layar penuh.

Kami berupaya keras untuk memperkenalkan API ini ke platform web dengan browser lain, dan kami senang dapat segera menghadirkannya kepada developer, memenuhi permintaan developer selama bertahun-tahun, dan mengisi kesenjangan yang signifikan di platform web.


Seperti biasa, beri tahu kami pendapat Anda melalui Twitter atau komentar di bawah, dan kirimkan bug ke crbug.com/new.