ウェブ機能:
moveBefore()
appendChild() や insertBefore() などの従来の方法を使用して、DOM 内で開いている <dialog>、popover、または全画面表示要素を移動すると、ブラウザは暗黙的に要素を DOM から削除して再挿入します。この削除により状態がリセットされ、開いているモーダル、ポップオーバー、全画面表示の要素が突然閉じられます。
ユーザー エクスペリエンスを中断したり、最上位要素を閉じたりせずに最上位要素を再親化するには、代わりにアトミック moveBefore() API を使用します。
開いている最上位レイヤ要素の親を再設定する
moveBefore() は、移動するノードと、その前に挿入する参照ノード(または新しい親の末尾に追加する null)の 2 つの引数を取ります。
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();
}
}