原文地址:Meet the New Dialog Element
做者:Keithjavascript
不到一个月前,HTML 5.2
正式成为W3C
的推荐标准(REC
),其中,推出了一个新的原生模态对话框元素<dialog>
,乍一看,可能感受它就是一个新增的元素,然而,做者最近在玩的时候,发现它确实是一个值得期待和颇有意思的元素,在这里分享给你们
这是 <diglog>
最基础的示例css
<dialog open> Native dialog box! </dialog>
其中,open
属性表示此时 dialog
是可见的,若是没有 open
,dialog
将会隐藏,你可使用 JavaScipt
将它显现出来,此时,dialog
渲染以下html
它 绝对定位
于页面之上,就如咱们指望的同样,出如今内容的上方,而且 水平居中
,默认状况下,它 和内容同样宽
java
JavaScipt
有几个 方法
和 属性
能够很方便地处理 dialog
元素,使用最多的可能仍是 showModal()
和 close()
chrome
const modal = document.querySelector('dialog'); // makes modal appear (adds `open` attribute) modal.showModal(); // hides modal (removes `open` attribute) modal.close();
当你使用 showModal()
来打开 dialog
时,将会在 dialog
周围加一层阴影,阻止用户与 非 diglog
元素的交互,默认状况下,阴影是 彻底透明
的,你可使用 CSS
来修改它npm
按 Esc
能够关闭 dialog
,你也能够提供一个按钮来触发 close()
浏览器
还有一个方法是 show()
,它也可让 dialog
显现,但与 showModal()
不一样的是它没有阴影,用户能够与非 dialog
元素进行交互app
目前,只有 chrome
支持 <dialog>
,Firefox
须要在 about:config
里容许 dom.dialog_element.enabled
才能正常使用,我猜测,Firefox
在不久的未来就会支持dom
上图为 caniuse.com 关于 dialog
特性主流浏览器的兼容状况ide
幸运的是,咱们可使用 dialog-polyfill 来缓解这种尴尬,它既提供了 JavaScript
的行为,也包含了默认的样式,咱们可使用 npm
来安装它,也可使用 <script>
标签来引用它。目前,它已支持各主流浏览器,包括 IE 9
及其以上版本
只是,在使用它时,每一个 dialog
须要使用下面语句进行初始化
dialogPolyfill.registerDialog(dialog);
而且,它并不会取代浏览器原生的行为
打开和关闭模态框是最基本的,但这是确定不够的,<dialog>
最开始时样式是不怎么好看的,所以,咱们须要自定义它的样式,此外,咱们能够经过设置伪元素 ::backdrop
来优化 <dialog>
显现时背影的样式
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
里添加更多的内容,通常包括 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
,你就能获得你想要的
一般,咱们指望能从 dialog
中获取一些用户的信息。关闭 dialog
时,咱们能够给 close()
传递一个 string
,而后经过 dialog
元素的 returnValue
属性来获取
modal.close('Accepted'); console.log(modal.returnValue); // logs `Accepted`
固然,还存在额外的事件咱们能够监听,其中,最经常使用的多是 close
(关闭 dialog
时触发),还有 cancel
(用户按 Esc
关闭 dialog
时触发)
此外,咱们可能还指望点击 dialog
旁边的阴影来关闭,固然,这也是有解决办法的。点击阴影会触发 dialog
的点击事件,若是 dialog
的子元素占满了整个 dialog
,那么咱们能够经过监听 dialog
的点击,当 target
为 modal
时来关闭它
modal.addEventListener('click', (event) => { if (event.target === modal) { modal.close('cancelled'); } });
固然,这不是完美的,但它确实是有效的,若是你有更好的方式,欢迎在评论中交流
说了这么多,不如本身实际演练一番,做者也作了一个 demo,欢迎参考