原文地址:Meet the New Dialog Element
作者:Keith
不到一個月前,
HTML 5.2
正式成為W3C
的推薦標(biāo)準(zhǔn)(REC
),其中,推出了一個新的原生模態(tài)對話框元素<dialog>
,乍一看,可能感覺它就是一個新增的元素,然而,作者最近在玩的時候,發(fā)現(xiàn)它確實是一個值得期待和很有意思的元素,在這里分享給大家
這是 <diglog>
最基礎(chǔ)的示例
<dialog open>
Native dialog box!
</dialog>
其中,open
屬性表示此時 dialog
是可見的,如果沒有 open
,dialog
將會隱藏,你可以使用 JavaScipt
將它顯現(xiàn)出來,此時,dialog
渲染如下
它 絕對定位
于頁面之上,就如我們期望的一樣,出現(xiàn)在內(nèi)容的上方,并且 水平居中
,默認(rèn)情況下,它 和內(nèi)容一樣寬
基本操作
JavaScipt
有幾個 方法
和 屬性
可以很方便地處理 dialog
元素,使用最多的可能還是 showModal()
和 close()
const modal = document.querySelector('dialog');
// makes modal appear (adds `open` attribute)
modal.showModal();
// hides modal (removes `open` attribute)
modal.close();
當(dāng)你使用 showModal()
來打開 dialog
時,將會在 dialog
周圍加一層陰影,阻止用戶與 非 diglog
元素的交互,默認(rèn)情況下,陰影是 完全透明
的,你可以使用 CSS
來修改它
按 Esc
可以關(guān)閉 dialog
,你也可以提供一個按鈕來觸發(fā) close()
還有一個方法是 show()
,它也可以讓 dialog
顯現(xiàn),但與 showModal()
不同的是它沒有陰影,用戶可以與非 dialog
元素進(jìn)行交互
瀏覽器支持和 Polyfill
目前,只有 chrome
支持 <dialog>
,Firefox
需要在 about:config
里允許 dom.dialog_element.enabled
才能正常使用,我猜想,Firefox
在不久的將來就會支持
上圖為 caniuse.com 關(guān)于 dialog
特性主流瀏覽器的兼容情況
幸運的是,我們可以使用 dialog-polyfill 來緩解這種尷尬,它既提供了 JavaScript
的行為,也包含了默認(rèn)的樣式,我們可以使用 npm
來安裝它,也可以使用 <script>
標(biāo)簽來引用它。目前,它已支持各主流瀏覽器,包括 IE 9
及其以上版本
只是,在使用它時,每個 dialog
需要使用下面語句進(jìn)行初始化
dialogPolyfill.registerDialog(dialog);
并且,它并不會取代瀏覽器原生的行為
樣式
打開和關(guān)閉模態(tài)框是最基本的,但這是肯定不夠的,<dialog>
最開始時樣式是不怎么好看的,因此,我們需要自定義它的樣式,此外,我們可以通過設(shè)置偽元素 ::backdrop
來優(yōu)化 <dialog>
顯現(xiàn)時背影的樣式
dialog {
padding: 0;
width: 478px;
text-align: center;
vertical-align: middle;
border-radius: 5px;
border: 0;
}
dialog::backdrop {
background-color: rgba(0, 0, 0, 0.1);
}
為了兼容老的瀏覽器,使用 polyfill
時,::backdrop
是不起作用的,但 polyfill
會在 dialog
后面添加一個 .backdrop
元素,我們可以像下面這樣定位它
dialog + .backdrop {
background-color: rgba(0, 0, 0, 0.4);
}
接下來,是時候向 bialog
里添加更多的內(nèi)容,一般包括 header
, body
和 footer
<dialog id="sweet-modal">
<h3 class="modal-header">sweet dialog</h3>
<div class="modal-body">
<p>This is a sweet dialog, which is much better.</p>
</div>
<footer class="modal-footer">
<button id="get-it" type="button">Get</button>
</footer>
</dialog>
最后,在添加一些 CSS
,你就能得到你想要的
進(jìn)階操作
通常,我們期望能從 dialog
中獲取一些用戶的信息。關(guān)閉 dialog
時,我們可以給 close()
傳遞一個 string
,然后通過 dialog
元素的 returnValue
屬性來獲取
modal.close('Accepted');
console.log(modal.returnValue); // logs `Accepted`
當(dāng)然,還存在額外的事件我們可以監(jiān)聽,其中,最常用的可能是 close
(關(guān)閉 dialog
時觸發(fā)),還有 cancel
(用戶按 Esc
關(guān)閉 dialog
時觸發(fā))
此外,我們可能還期望點擊 dialog
旁邊的陰影來關(guān)閉,當(dāng)然,這也是有解決辦法的。點擊陰影會觸發(fā) dialog
的點擊事件,如果 dialog
的子元素占滿了整個 dialog
,那么我們可以通過監(jiān)聽 dialog
的點擊,當(dāng) target
為 modal
時來關(guān)閉它
modal.addEventListener('click', (event) => {
if (event.target === modal) {
modal.close('cancelled');
}
});
當(dāng)然,這不是完美的,但它確實是有效的,如果你有更好的方式,歡迎在評論中交流
總結(jié)
說了這么多,不如自己實際演練一番,作者也做了一個 demo,歡迎參考