跳至主要内容

[HTML] dialog

兩種 Dialog

<dialog> 可以分成 modalnon-modal dialog:

ModalNon-modal
操作方式使用 .showModal() 開啟 modal使用 .show() 開啟 modal;(不建議)或使用了 open attribute
特性不能和頁面上的其他區域互動(除了 scroll)可以和頁面上的其他區域互動
可以透過 .close() 或 ESC 關閉可以透過 .close() 關閉
樣式::backdrop 和預設的樣式沒有 ::backdrop
實際的位置在 DOM 最外層(top-player)實際位置沒有改變
預設就是置中在畫面中央(水平垂直置中)水平置中

在 Dialog 中使用 Form

送出表單的行為

<dialog> 裡面有 <form> 時,如果:

  • <form> 上有使用 method="dialog",也就是 <form method="dialog">
  • 或針對送出 form 的 <button> 使用 <button formmethod="dialog">

則當使用者試著送出這個表單時:

  • 這個表單並不會實際被送出(submit),而是會關閉 dialog
  • 再次打開這個 dialog 時,上次填寫的內容依然會留著

表單中有 required 的情況

如果這個 form 裡面有 required 的 input,只有在 required value 有填的情況下,才能關閉 dialog,除非

  • 主動呼叫 .close()
  • 使用 formnovalidate,例如 <input type="submit" formnovalidate>

returnValue

預設的情況下, returnValue 會是「空字串」,或是「submit button 的 value」,例如,<button formmethod="dialog" value="foobar">Confirm</button>,則使用者按下 Confirm 是,dialog.returnValue 則會是 foobar

要改變 dialog.returnValue 的一種做法是在呼叫 .close() 是把值傳進去,例如:dialog.close('foobar'); 則拿到的 dialog.returnValue 就會是 foobar

點擊 modal 外面以關閉 dialog

如果你使用的是 modal,預設的情況下,點擊 modal 內容外面並不會關閉 modal,但很多情況下,我們希望能有這樣的行為。

要這麽做可以使用這段 JavaScript script:

// Source: https://blog.webdevsimplified.com/2023-04/html-dialog/

// 這個作法只能用在 modal dialog
dialog.addEventListener('click', (e) => {
const dialogDimensions = dialog.getBoundingClientRect();
if (
e.clientX < dialogDimensions.left ||
e.clientX > dialogDimensions.right ||
e.clientY < dialogDimensions.top ||
e.clientY > dialogDimensions.bottom
) {
dialog.close();
}
});

但要注意的是,這個作法只能用在 modal dialog,不能用在 non-modal dialog,因為 modal dialog 的 dialog element(包含 backdrop)會佔據整個畫面,所以監聽它的 click event 才有用;但 non-modal dialog 只有 dialog element 本身,監聽 click 只會監聽到 dialog 本身,dialog 外被點擊是不會觸發 click 事件。