这是 <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 地址 https://codepen.io/FengShangWuQi/pen/qpMgZB
来源: http://www.qdfuns.com/article/46360/0ad6c845bafebd188f130b2bd4aa5938.html