欢送关注我的公众号:前端侦探
想必大家都晓得 HTML5
中有 dialog
这样一个标签,顾名思义,就是“弹窗”。除了有良好的语义外,随着浏览器的不断更新迭代,还呈现了许多你可能不晓得的个性,疾速理解一下吧~
一、关上和敞开办法
首先,在不查阅任何官网文档的状况下,先做一个抉择题目
请问:上面哪组办法(关上 / 敞开)是非法的?
思考 10 秒 …
🤔
🤔
🤔
🤔
正确答案是 C
,也就是
// 关上弹窗
dialog.show()
// 关上敞开
dialog.close()
很多同学可能会感觉是 A 或者 B,然而官网文档上确是 C,的确是一个令人蛊惑的办法。至于起因,有解释说,dialog
是存在于页面上的元素,所以关上用show
,而敞开示意中断弹窗内的行为,所以用close
,只能说有分割,但比拟牵强,或者就是标准设计忽略了,大家记住就好。
还有一个,如果须要弹窗默认显示,大家先猜猜看?
再来思考 10 秒 …
🤔
🤔
🤔
🤔
正确答案是 B
,也就是
<dialog open></dialog>
🤣是不是又和下面的 show()
对不上了?
除了
dialog
元素,details
元素的关上属性也是open
二、表单提交个性
弹窗很多时候的作用都是充当表单输出。
比方一个弹窗中须要有一个敞开或者勾销按钮
<dialog>
<h3> 欢送关注前端侦探 </h3>
<button> 敞开 </button>
</dialog>
通常状况下,咱们可能须要用到后面提到的 dialog.close()
办法来被动敞开弹窗。
其实,还能够通过表单个性实现这样一个成果,具体做法是:
- 在
dialog
中嵌套一层form
- 给
form
增加一个method=dialog
属性
如下
<dialog>
<form method="dialog">
<h3> 欢送关注前端侦探 </h3>
<button> 敞开 </button>
</form>
</dialog>
这样就 能够不必绑定额定的事件来实现敞开性能 了,成果如下
其实起因就在于表单上的 method=dialog
属性,如果表单在 dialog
元素中,提交时就会触发敞开对话框
https://developer.mozilla.org…
默认状况下,表单里的 button
都会触发提交,等同于 type=submit
,但如果设置了type=button
或者type=reset
,则不会触发表单提交,天然也不会敞开弹窗
<dialog>
<form method="dialog">
<h3> 欢送关注前端侦探 </h3>
<button> 敞开 </button>
<button type="button"> 不会敞开 </button>
</form>
</dialog>
成果如下
另外还有一个小个性,dialog
还有一个 returnValue
属性,能够返回表单中提交按钮的 value
值
<dialog>
<form method="dialog">
<h3> 欢送关注前端侦探 </h3>
<button value="AAA"> 提交 </button>
</form>
</dialog>
在提交后能够打印弹窗的returnValue
,如下
不过临时还没有想到很有用的场景
三、模态窗口个性
弹窗除了能够通过 dialog.show()
关上之外,还提供了一个模态窗口,办法是
dailog.showModal()
通过这个办法关上的弹窗,会自带一个半透明的背景,并且齐全程度垂直居中
这个半透明的背景并不是一般的元素,而是一个叫做::backdrop 的伪元素管制的,并且目前只有通过 dailog.showModal()
这个办法能力生成
要自定义背景也很容易
dialog::backdrop {background: rgba(255,0,0,.25);
}
这样就变成了半透明红色
如果心愿关上弹窗有动画,能够自定义默认款式,通过 visibility
的形式实现暗藏显示
dialog{
position: fixed;
margin: auto;
inset: 0;
width: fit-content;
height: fit-content;
display: block;
visibility: hidden;
opacity: 0;
transform: translateY(100px);
transition: .2s;
}
dialog[open] {
visibility: visible;
opacity: 1;
transform: translateY(0);
}
成果如下
其实这里我是不太倡议动画的,弹窗就是要反馈疾速,加了动画反而会连累整体。
另外,还能够通过 :modal
伪类来辨别是一般弹窗还是模态弹窗
dialog:modal{/* 模态弹窗 */}
dialog:not(:modal){/* 一般弹窗 */}
这样能够更多进行自定义行为
模态弹窗还有一个十分省心的点,就是无需关注层级。它有一套十分直观的规定,哪个后关上,哪个层级最高,比方这样两个弹窗
<dialog id="dialog2">
...
</dialog>
<dialog id="dialog1">
...
<button type="button"> 关上弹窗 2 </button>
...
</dialog>
在不指定层级的状况下,必定是前面的层级更高,但如果是通过 dialog.showModal
关上,就十分直观了,后关上的弹窗必定会笼罩后面的,成果如下
说到这里,我又想到了一些 UI 组件库里大到可怕的z-index
,大概率就是通过计算得出的
四、焦点隔离个性
除了下面一些比拟直观的个性外,还有一些可能会疏忽的,比方焦点的管制。
默认状况下,关上弹窗后会主动聚焦到弹窗内的第一个可聚焦元素上
还能够有 input
输入框
<dialog>
<form method="dialog">
<h3> 欢送关注前端侦探 </h3>
<input name="txt">
<button> 敞开 </button>
</form>
</dialog>
关上弹窗后能够间接输出,无需额定操作,几乎不要太不便
留神,留神,留神:经测试发现,如果增加了关上动画,聚焦个性就会生效
当然,这些只是小儿科,一点点额定的 JS 也能解决,上面介绍一个零碎级别的 焦点隔离个性 。什么意思呢?就是说在关上弹窗后,弹窗就成了一个独立的载体,焦点只能在这个范畴内挪动,也就是说,无论tab
键如何切换,焦点不会跑到弹窗里面去,上面是一个比照成果
- 一般弹窗成果
- 模态弹窗成果
这个成果其实是和新出的 inert
属性作用比拟相似的,然而要比 inert
呈现的更早,也能够说是通过 inert
属性将这种隔离个性通用化了,让平民老百姓也能够享受这种高级个性。有趣味的能够拜访我之前的这篇文章:疾速理解 inert 属性
五、顶层个性 top-layer
最初介绍一个即使是 JS 也无奈模仿的零碎级新个性,top-layer
。
不晓得大家有没有遇到这样的问题,有些弹窗因为业务须要,不得已写在了某些容器上面,即使是 fixed
定位,也会有生效的时候,比方上面这个例子,父容器如果有 transform
相干属性并且超出暗藏,就会呈现这样被裁剪的情景
下面这个例子来源于 xy-ui 中的 dialog 组件,后续优化,敬请期待~
在以前,或者说很多框架中,都会想方法把弹窗放到最外层的 body
下,这样就不受影响了,比方上面是 vue3
中的解决形式
<div>
<Teleport to="body"> <!-- 将子内容传送到 body 下 -->
<dialog></dialog>
</Teleport>
</div>
但当初,有了全新的 top-layer
,所有都好办了,比方上面是一个通过 dialog.showModal()
关上的弹窗
你会发现,尽管 dialog
依然在原来地位上,但真正渲染到了一个 #top-layer
的层级上,这个层级十分非凡,曾经超过了 html
文档流,能够说是独一档的存在,这样,无论的 dialog
在什么地位,最初渲染的中央其实都在 #top-layer
层级上,天然也不会被父容器裁剪被暗藏了,示意如下
是不是和古代框架有些许相似呢?上面是一个弹窗里嵌套另外一个弹窗
<dialog id="dialog1">
...
<button type="button" > 关上弹窗 2 </button>
<dialog id="dialog2">
...
</dialog>
</dialog>
成果如下
其实这也是后关上的弹窗永远要高于之前弹窗的起因,#top-layer
是动态创建的,只有关上的弹窗才会渲染到该层级之下。
另外,经测试发现,firefox
以及 safari
尽管在开发者工具上看不到 #top-layer
,然而dialog
体现根本简直统一,应该是曾经成为了标准规范,日后能够放心使用。
六、dom 其实也是在一直倒退的
dialog
其实我在两三年之前就有钻研过,那时还没有这么多新个性,也有可能是钻研不精,起初就搁置了,而后最近在我的项目中用了dialog
,无心中又发现了很多有意思的新个性,这意味着,dom 其实也是在一直倒退的,有必要把以前曾经用过的再翻出来过一遍,说不定还能发现意想不到的后果,上面是要点总结
dialog
的关上和敞开办法很蛊惑,别离是show() / close()
dialog
中表单元素在增加method=dialog
属性之后,只有触发表单提交就会主动敞开弹窗,无需额定 js- 通过
showModal()
能够关上模态弹窗,并且后关上的弹窗永远比先关上的弹窗层级要高,无需手动计算层级 - 关上弹窗会主动聚焦到弹窗内的第一个可聚焦元素,不便疾速输出
- 模态弹窗的焦点不会聚焦到弹窗内部,这和
inert
个性比拟相似 - 模态弹窗其实是渲染到了
html
文档流之外,一个叫#top-layer
的层级上,因而不会受到原父容器的影响
很多同学往往过于关注 JavaScript
和古代风行框架,而漠视了原生 dom
的倒退,但原生 dom
带来的很多新个性往往是零碎级别的,有可能你辛辛苦苦实现的一个性能,原生一个属性就搞定,而且成果更好,所以请不要忘了原生。最初,如果感觉还不错,对你有帮忙的话,欢送 点赞、珍藏、转发❤❤❤
欢送关注我的公众号:前端侦探