永久性頂層 UI

網頁功能: moveBefore()

使用 appendChild() 或 insertBefore() 等傳統方法,在 DOM 中移動開啟的 <dialog>、popover 或全螢幕元素時,瀏覽器會隱含地從 DOM 中移除該元素,然後重新插入。這項移除作業會重設狀態,導致開啟的互動視窗、彈出式視窗和全螢幕元素突然關閉。

如要重新設定頂層元素的父項,而不中斷使用者體驗或關閉元素,請改用原子 moveBefore() API。

重新設定開啟的頂層元素

moveBefore() 接受兩個引數:要移動的節點,以及要插入之前的參考節點 (或 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();
  }
}