- 原文地址:Meet the New Dialog Element
- 原文作者:keithjgrant
- 譯文出自:掘金翻譯計劃
- 本文永久連結:github.com/xitu/gold-m…
- 譯者:FateZeros
- 校對者:ryouaki PCAaron
迎接新的 Dialog 元素
HTML 5.2 為原生彈窗對話方塊引入了一個新的 <dialog>
元素。 乍一看,它似乎相當簡單(本來就是),但當我和它打交道的過程中,我發現有一些很棒的新特性很容易被忽視掉。
在本文的最後我加上了一個完整可行的 Demo ,但是如果你想在閱讀的過程中也檢視的話,你可以看這裡.
這是一個基本的彈窗對話方塊標記:
<dialog open>
Native dialog box!
</dialog>
複製程式碼
open
屬性意味著對話方塊是可見的。沒有它,除非你用 JavaSript 使它出現,否則它就是隱藏的。在新增樣式之前,對話方塊渲染如下所示:
它在頁面中是絕對定位的,因此它會按照你所期望的那樣出現在其他內容前面,並且水平居中。預設情況下,它和內容等寬。
基本操作
JavaScript 有幾個方法和屬性可以方便地處理 <dialog>
元素。你可能最需要的兩個方法是 showModal()
和 close()
。
const modal = document.querySelector(`dialog`);
// 使對話方塊出現(新增 `open` 屬性)
modal.showModal();
// 隱藏對話方塊(移除 `open` 屬性)
modal.close();
複製程式碼
當你用 showModal()
開啟對話方塊的時候,頁面會新增一層背景,阻止使用者與對話方塊之外的內容互動。預設情況下,這層背景是完全透明的,但是你可以改變 CSS 屬性使它可見(後面會有更多介紹)。
按 Esc 鍵會關閉對話方塊,你也可以提供一個關閉按鈕來觸發 close()
方法。
還有第三個方法,show()
也會讓對話方塊出現,但不會伴隨背景層。使用者仍可以和對話方塊之外的可見的元素進行互動。
瀏覽器支援和 Polyfill
現在,只有 Chrome 支援 <dialog>
。Firefox 提供了預設樣式,但是 JavaScript API 僅在標誌後啟用。我猜想 Firefox 會很快支援它。
慶幸地是,polyfill 提供了 JavaScript 事件和預設樣式。用 npm 安裝 dialog-polyfill
來使用它 —— 或者使用常用的舊的 <script>
標籤。這樣 <dialog>
就可以在 IE9及以上版本中使用了。
當使用 polyfill 時,頁面上的每個對話方塊都需要被初始化:
dialogPolyfill.registerDialog(modal);
複製程式碼
這不會替代擁有它的瀏覽器中的原生事件。
樣式
開啟和關閉對話方塊完成了,但是它起初看起來並不專業。我們像給其他元素新增樣式那樣,給對話方塊新增樣式。背景層可以用新的 ::backdrop
偽元素來設計。
dialog {
padding: 0;
border: 0;
border-radius: 0.6rem;
box-shadow: 0 0 1em black;
}
dialog::backdrop {
/* make the backdrop a semi-transparent black */
background-color: rgba(0, 0, 0, 0.4);
}
複製程式碼
對於那些需要使用 polyfill 的老瀏覽器,這個偽元素選擇器將不會起作用,然而,在這個對話方塊位置後,polyfill 會立即新增一個 .backdrop
元素。你可以像這樣用 CSS 來定位它:
dialog + .backdrop {
background-color: rgba(0, 0, 0, 0.4);
}
複製程式碼
新增更多的標記來提供樣式的鉤子。一個常用的做法是將對話方塊劃分為標題,正文和頁尾:
<dialog id="demo-modal">
<h3 class="modal-header">A native modal dialog box</h3>
<div class="modal-body">
<p>Finally, HTML has a native dialog box element! This is fantastic.</p>
<p>And a polyfill makes this usable today.</p>
</div>
<footer class="modal-footer">
<button id="close" type="button">close</button>
</footer>
</dialog>
複製程式碼
給它新增一些 CSS ,你可以讓對話方塊做成任何你想要的外觀:
更多控制
通常,我們想要從對話方塊中獲得更多使用者反饋。當關閉對話方塊時,你可以傳遞一個字串值到 close()
方法。該值將會被賦值給對話方塊 DOM 元素的 retrunValue
屬性,因此它可以在後面被讀取到:
modal.close(`Accepted`);
console.log(modal.returnValue); // logs `Accepted`
複製程式碼
還有一些事件你可以監聽。兩個有用的事件是 close
(當對話方塊關閉的時候觸發)和 cancel
(當使用者按了 Esc 關閉對話方塊時觸發)。
有一件事似乎被忘掉了,當背景層被點選時能夠關閉對話方塊,但有一個變通方案。當點選背景層時,觸發 <dialog>
的點選事件作為事件目標。並且,如果你構造對話方塊使得子元素填充了整個對話方塊,那些子元素將會被作為對話方塊內任何點選的目標。這種方式,你可以監聽對話方塊上的點選,當點選事件的目標是對話方塊本身的時候關閉它:
modal.addEventListener(`click`, (event) => {
if (event.target === modal) {
modal.close(`cancelled`);
}
});
複製程式碼
雖然不完美,但是起了作用。如果你找到了更好的方法來檢測背景層上的點選,請讓我知道。
完整可行的 Demo
我在下面的示例中演示了很多東西。親自實踐下,看你還能用 <dialog>
做些什麼。它包含了 polyfill,所以它應該能在大多數瀏覽器中執行。
請參閱 Keith J. Grant (@keithjgrant) 在 CodePen 上的 。
掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。