一起来看 HTML 5.2 中新的原生元素 <dialog> - 枫上雾棋的日志 - SegmentFault
source link: https://segmentfault.com/a/1190000012894864?
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
一起来看 HTML 5.2 中新的原生元素 <dialog>
原文地址:Meet the New Dialog Element
作者:Keith
不到一个月前,HTML 5.2
正式成为W3C
的推荐标准(REC
),其中,推出了一个新的原生模态对话框元素<dialog>
,乍一看,可能感觉它就是一个新增的元素,然而,作者最近在玩的时候,发现它确实是一个值得期待和很有意思的元素,在这里分享给大家
这是 <diglog>
最基础的示例
<dialog open> Native dialog box! </dialog>
其中,open
属性表示此时 dialog
是可见的,如果没有 open
,dialog
将会隐藏,你可以使用 JavaScipt
将它显现出来,此时,dialog
渲染如下
它 绝对定位
于页面之上,就如我们期望的一样,出现在内容的上方,并且 水平居中
,默认情况下,它 和内容一样宽
JavaScipt
有几个 方法
和 属性
可以很方便地处理 dialog
元素,使用最多的可能还是 showModal()
和 close()
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
来修改它
按 Esc
可以关闭 dialog
,你也可以提供一个按钮来触发 close()
还有一个方法是 show()
,它也可以让 dialog
显现,但与 showModal()
不同的是它没有阴影,用户可以与非 dialog
元素进行交互
浏览器支持和 Polyfill
目前,只有 chrome
支持 <dialog>
,Firefox
需要在 about:config
里允许 dom.dialog_element.enabled
才能正常使用,我猜想,Firefox
在不久的将来就会支持
上图为 caniuse.com 关于 dialog
特性主流浏览器的兼容情况
幸运的是,我们可以使用 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,欢迎参考
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK