前言
继 html5 新增了诸多新的标签之后, HTML5.2 又引入了几个现代标签, 其中就包括 <dialog> 标签. 下面跟大家一块学习一下这个标签.
举个栗子
下来看一个最简单的例子:
以上就是 dialog 的原生态样式, 未添加任何额外样式. 这在 Chrome 和 Firefox 里表现是一致的, 它们各自的默认样式是这样的, 基本一致 --
Chrome:
Firefox:
嫌丑?! 如果给它加上瘦脸 (去掉默认样式), 加上美颜 (CSS), 再加上特效 (js), 一样可以十分性感.
两个属性
open
该属性意味着该对话框是可见的, 没有它, 这个对话框就会隐藏起来, 直到你使用 JavaScript 来显示它, 其实就是给它加上了 open 属性.
returnValue
用来获取 close 时传入的参数, 看下面.
三个方法
- show()
- showModal()
两个方法相同点都是打开弹窗, 即都会给 dialog 元素添加一个 open 属性. 不同点:
唯一区别就是 show() 会按照其在 DOM 流中的位置显示 dialog, 没有遮罩, 而 showModal() 会出现遮罩, 并且自动做了按键监控, 即点击 esc 键, 弹窗会关闭
大多数情况下, 我们会使用便利的 showModal() 方法来而不使用 show() 方法.
close()
会关闭弹窗, 即会删除 open 属性, 并且可以携带一个参数作为额外数据, 传入的值可以通过 dialog.returnValue 获取.
两个事件
close
当 modal 关闭的时候触发
cancel
当按下 ESC 关闭模态框的时候触发
在各事件的事件对象 event.target 里, 同样可以看到 close() 方法传入的参数, 即 event.target.returnValue.
一个伪元素
::backdrop
是 dialog 伪元素, 用来设置弹窗遮罩的样式, 用法如下
- dialog::backdrop {
- background-color: rgba(0, 0, 0, 0.4);
- }
浏览器对 backdrop 也有默认的样式. chrome:
再举个栗子
部分代码
- methods: {
- onShow () {
- this.dialog.showModal();
- }
- },
- mounted () {
- this.dialog = this.$refs.dialog2;
- let closeBtn = this.dialog.querySelector('.js-close');
- let confirmBtn = this.dialog.querySelector('.js-confirm');
- let cancelBtn = this.dialog.querySelector('.js-cancel');
- // 按 esc 关闭弹窗, 同时会触发 close 事件
- this.dialog.addEventListener('cancel', e => {
- // 不写这句也会关闭, 这里主要是为了携带数据及演示监听 cancel 事件
- this.dialog.close('按 esc 关闭');
- });
- // 关闭
- this.dialog.addEventListener('close', e => {
- let returnValue = this.dialog.returnValue;
- this.dialog.returnValue = '';
- returnValue !== '' && this.$notify({
- title: 'returnValue',
- message: returnValue
- });
- });
- // 点击遮罩关闭, 事件注册在 dialog 上
- this.dialog.addEventListener('click', (event) => {
- if (event.target === this.dialog) {
- // 关闭, 并携带数据
- this.dialog.close('点击了遮罩关闭');
- }
- });
- // 点 × 关闭
- closeBtn.addEventListener('click', e => {
- this.dialog.close('点击了关闭');
- });
- // 点确定
- confirmBtn.addEventListener('click', e => {
- this.dialog.close('点击了确定');
- });
- // 点取消
- cancelBtn.addEventListener('click', e => {
- this.dialog.close('点击了取消');
- });
- }
- /* 改变 dialog 样式 */
- dialog {
- position: fixed;
- margin: 0;
- left: 50%;
- top: 50%;
- transform: translate(-50%, -50%);
- min-width: 300px;
- max-width: 80%;
- border: none;
- box-shadow: 1px 1px 1px rgba(0, 0, 0, .3);
- }
- dialog[open] {
- animation: slide-up 0.4s ease-out;
- }
- /* 改变遮罩样式 */
- dialog::backdrop {
- background: rgba(0, 0, 0, 0.5);
- }
- @keyframes slide-up {
- 0% {
- opacity: 0;
- transform: translate(-50%, -40%);
- }
- 100% {
- opacity: 1;
- transform: translate(-50%, -50%);
- }
- }
- polyfill
What?! 浏览器不支持? 手机端没反应?!!
木有关系. 这里有一个 https://github.com/GoogleChrome/dialog-polyfill , 通过少许的额外代码, 依然可以实现实现上面的功能. 只要引入该 js,js 中在弹窗对象后面添加一句:
dialogPolyfill.registerDialog(this.dialog);
再引入它的 css(很简单) 即可. 有兴趣的同学可以试试, 这里不再赘述~ 不支持的浏览器再试下这个 Demo:
最后一个栗子
参考资料
- <dialog>: The Dialog element https://developer.mozilla.org/en-US/docs/web/HTML/Element/dialog
- https://codepen.io/keithjgrant/pen/eyMMVL
- Native Popups and Modals With the HTML5 "dialog" Element https://webdesign.tutsplus.com/tutorials/native-popups-and-modals-with-the-html5-dialog-element--cms-23876
初探 HTML5.x 新特性dialog标签 https://yq.aliyun.com/articles/374584
来源: https://juejin.im/entry/5b34a26e51882574dd4ae3b1