Chúng tôi rất vui mừng được công bố moveBefore()
DOM API mới, có trong Chrome phiên bản 133, giúp bạn dễ dàng di chuyển các phần tử trong DOM mà không làm mất trạng thái. Hãy đọc tiếp để tìm hiểu cách sử dụng tính năng này trong dự án của bạn!
Mất trạng thái trong quá trình đột biến DOM
Bạn có sử dụng API appendChild()
để chèn các phần tử mới vào DOM không? Nhiều người cũng vậy, nhưng bạn đã bao giờ thử gọi API này (hoặc insertBefore()
hoặc bất kỳ API chèn nào khác cho vấn đề đó) bằng một phần tử đã có trong DOM chưa? Nếu có, bạn có thể không nhận ra rằng việc này hoạt động êm ái bằng cách xoá phần tử khỏi phần tử mẹ cũ trước, rồi chèn lại phần tử đó vào phần tử mẹ mới. Đó là vì Mô hình đối tượng tài liệu chỉ có các thao tác xoá và chèn nguyên gốc kể từ khi bản nháp Tiêu chuẩn DOM đầu tiên được giới thiệu vào năm 1998. Bất cứ khi nào bạn nghĩ rằng mình đang "di chuyển" một phần tử trong DOM từ vị trí này sang vị trí khác, thì thực sự bạn đang xoá và chèn phần tử đó.
Việc "di chuyển" thực sự là "xoá và chèn" thường không ảnh hưởng đến trải nghiệm người dùng. Ví dụ: khi "di chuyển" <p>
trong DOM, hai thao tác này không gây ra hiệu ứng phụ gây gián đoạn, nhưng khi di chuyển các nút phức tạp chứa trạng thái quan trọng (như phần tử <iframe>
, phần tử ở chế độ toàn màn hình, ảnh động CSS, v.v.), thao tác "xoá" ngầm ẩn sẽ đặt lại tất cả các loại trạng thái.
Điều này có thể gây ra những tác dụng phụ gây gián đoạn đáng ngạc nhiên
Bạn có thể xem loại trạng thái được đặt lại trong trang web minh hoạ giữ nguyên trạng thái bằng cách thử nghiệm các thao tác trong cây DOM. Ví dụ sau đây cho thấy ảnh động CSS và trạng thái <iframe>
được đặt lại khi di chuyển các phần tử từ vùng chứa mẹ sang vùng chứa mẹ khác.
Hạn chế này có thể khiến việc xây dựng trải nghiệm người dùng linh động trở nên khó khăn hoặc thậm chí là không thể. Người dùng sẽ cảm thấy khó chịu và bối rối khi trạng thái ứng dụng bị đặt lại một cách bí ẩn. Các tác giả khung JavaScript phải chịu phần lớn trách nhiệm này bằng cách dành vô số giờ để thiết kế lại mã giao diện người dùng xung quanh vấn đề này, tạo thư viện phức tạp như MorphDOM hoặc xử lý các báo cáo lỗi nêu bật các vấn đề mà họ không thể khắc phục.
API moveBefore()
mới
Chúng tôi đặt ra mục tiêu khắc phục vấn đề này bằng cách thêm một toán tử gốc mới vào DOM. Phương thức này được gọi là phương thức gốc "di chuyển" và được hiển thị cho nhà phát triển thông qua moveBefore()
DOM API mới.
moveBefore()
sử dụng các đối số giống như insertBefore()
, nhưng thay vì xoá và chèn lại các nút khi các nút đó đã được đính kèm vào DOM, API mới này di chuyển một cách nguyên tử nút mục tiêu vào phần tử mẹ mới mà không cần đặt lại hầu hết trạng thái. Cuối cùng, điều này cho phép các nhà phát triển JavaScript xây dựng trải nghiệm động bằng ảnh động có thể di chuyển, iframe, thành phần toàn màn hình và nhiều tính năng khác. Bạn có thể tự mình thử nghiệm tính năng này bằng cách bật cờ thử nghiệm chrome://flags/#atomic-move
và truy cập vào trang web minh hoạ của chúng tôi, hoặc bằng cách sử dụng phiên bản 133 của Chrome sau khi phiên bản này được phát hành vào ngày 4 tháng 2 năm 2025.
Sau đây là một số ví dụ về hành vi mà nguyên hàm mới này sẽ cho phép tác giả JavaScript đạt được:
- Duy trì trạng thái phát của video khi người dùng di chuyển trên trang web (cho dù video được cung cấp từ phần tử
<video>
hay<iframe>
). - Duy trì tiêu điểm của trường nhập dữ liệu của người dùng khi trường này được di chuyển trong DOM.
- Cho phép ảnh động kết thúc một cách mượt mà khi nội dung mới được thêm hoặc xoá khỏi DOM.
- Các thuật toán biến đổi có độ trung thực cao hơn để điều chỉnh DOM hiện có với nội dung mới.
- Giữ cho hộp thoại phương thức, cửa sổ bật lên và các thành phần toàn màn hình luôn mở.
Chúng tôi đang nỗ lực để ra mắt API này cho nền tảng web với các trình duyệt khác. Chúng tôi rất vui khi sớm có thể cung cấp API này cho nhà phát triển, đáp ứng các yêu cầu của nhà phát triển trong nhiều năm qua và lấp đầy một khoảng trống đáng kể trong nền tảng web.
Như thường lệ, hãy cho chúng tôi biết ý kiến của bạn qua Twitter hoặc bình luận bên dưới, đồng thời gửi lỗi đến crbug.com/new.