UI เลเยอร์บนสุดแบบถาวร

ฟีเจอร์บนเว็บ: moveBefore()

เมื่อย้ายองค์ประกอบ <dialog>, popover หรือองค์ประกอบแบบเต็มหน้าจอที่เปิดอยู่ใน DOM โดยใช้วิธีการแบบเดิม เช่น appendChild() หรือ insertBefore() เบราว์เซอร์จะนำองค์ประกอบออกจาก DOM โดยนัยและแทรกเข้าไปใหม่ การนำออกนี้จะรีเซ็ตสถานะ ซึ่งทำให้โมดัล ป๊อปโอเวอร์ และองค์ประกอบแบบเต็มหน้าจอที่เปิดอยู่ปิดลงอย่างกะทันหัน

หากต้องการเปลี่ยนระดับชั้นบนสุดโดยไม่รบกวนประสบการณ์ของผู้ใช้หรือปิดองค์ประกอบเหล่านั้น ให้ใช้ moveBefore() API แบบอะตอมแทน

การเปลี่ยนระดับชั้นบนสุดขององค์ประกอบที่เปิดอยู่

moveBefore() รับอาร์กิวเมนต์ 2 รายการ ได้แก่ โหนดที่จะย้าย และโหนดอ้างอิงที่จะแทรกก่อน (หรือ null เพื่อต่อท้ายโหนดหลักใหม่)

const newParent = document.getElementById('new-container');
const dialogElement = document.getElementById('my-dialog');

// MANDATORY: Use moveBefore to ensure the <dialog> or popover stays open.
// Passing null appends it to the end of newParent.
newParent.moveBefore(dialogElement, null);

กลยุทธ์สำรอง

เนื่องจาก moveBefore() เป็นการเพิ่มประสิทธิภาพแบบต่อเนื่อง คุณจึงต้องใช้การตรวจหาฟีเจอร์ก่อนเรียกใช้ สำหรับเบราว์เซอร์รุ่นเก่า คุณจะต้องเปลี่ยนกลับไปใช้การเปลี่ยนระดับชั้นบน-ล่างแบบดั้งเดิม

บังคับ: สำหรับองค์ประกอบ <dialog> ในเบราว์เซอร์ที่ไม่รองรับ การย้ายแบบดั้งเดิมจะปิดกล่องโต้ตอบ หากต้องการให้เปิดอยู่ คุณต้องเปิดอีกครั้งด้วยตนเองหลังจากย้าย

const targetParent = document.getElementById('target-container');
const popoverOrDialog = document.getElementById('my-top-layer-element');

// Check if moveBefore is supported
if ('moveBefore' in Element.prototype) {
  targetParent.moveBefore(popoverOrDialog, null);
} else {
  // Fallback: traditional move.
  // Note: This WILL close <dialog>, popover, and fullscreen elements.
  const wasOpen = popoverOrDialog.hasAttribute('open') || popoverOrDialog.matches(':popover-open');
  targetParent.insertBefore(popoverOrDialog, null);
  
  // Manually restore state if possible
  if (wasOpen && typeof popoverOrDialog.showModal === 'function') {
    popoverOrDialog.showModal();
  } else if (wasOpen && typeof popoverOrDialog.showPopover === 'function') {
    popoverOrDialog.showPopover();
  }
}