虽然 htmx 与 CSS 框架内置的对话框(如 Bootstrap 和 UIKit)配合得很好,但 htmx 也使得从头构建模态对话框变得非常简单。下面是一个快速示例,展示了一种构建它们的方法。
点击这里查看最终结果的演示:
我们将创建一个按钮,从服务器加载远程内容,然后在模态对话框中显示它。模态内容将被添加到 <body> 元素的末尾,在一个名为 #modal 的 div 中。
在这个演示中,我们将在 CSS 中定义一些漂亮的动画,然后使用一些 Hyperscript 在用户完成时从 DOM 中移除模态框。Hyperscript 与 htmx 并非 必需,但两者被设计为一起使用,并且它比 JavaScript 更适合编写异步和事件导向的代码,这就是为什么我们在这个示例中选择它的原因。
<button class="btn primary" hx-get="/modal" hx-target="body" hx-swap="beforeend">打开模态框</button>
<div id="modal" _="on closeModal add .closing then wait for animationend then remove me">
<div class="modal-underlay" _="on click trigger closeModal"></div>
<div class="modal-content">
<h1>模态对话框</h1>
这是模态内容。
您可以在这里放置任何内容,比如文本、表单或图像。
<br>
<br>
<button class="btn danger" _="on click trigger closeModal">关闭</button>
</div>
</div>
/***** 模态对话框 ****/
#modal {
/* 底层覆盖整个屏幕。 */
position: fixed;
top:0px;
bottom: 0px;
left:0px;
right:0px;
background-color:rgba(0,0,0,0.5);
z-index:1000;
/* Flexbox 垂直和水平居中 .modal-content */
display:flex;
flex-direction:column;
align-items:center;
/* 打开时动画 */
animation-name: fadeIn;
animation-duration:150ms;
animation-timing-function: ease;
}
#modal > .modal-underlay {
/* 底层占据整个视口。这仅在您希望点击以关闭弹出窗口时需要 */
position: absolute;
z-index: -1;
top:0px;
bottom:0px;
left: 0px;
right: 0px;
}
#modal > .modal-content {
/* 将可见对话框定位在窗口顶部附近 */
margin-top:10vh;
/* 可见对话框的尺寸 */
width:80%;
max-width:600px;
/* 可见对话框的显示属性 */
border:solid 1px #999;
border-radius:8px;
box-shadow: 0px 0px 20px 0px rgba(0,0,0,0.3);
background-color:white;
padding:20px;
/* 打开时动画 */
animation-name:zoomIn;
animation-duration:150ms;
animation-timing-function: ease;
}
#modal.closing {
/* 关闭时动画 */
animation-name: fadeOut;
animation-duration:150ms;
animation-timing-function: ease;
}
#modal.closing > .modal-content {
/* 关闭时动画 */
animation-name: zoomOut;
animation-duration:150ms;
animation-timing-function: ease;
}
@keyframes fadeIn {
0% {opacity: 0;}
100% {opacity: 1;}
}
@keyframes fadeOut {
0% {opacity: 1;}
100% {opacity: 0;}
}
@keyframes zoomIn {
0% {transform: scale(0.9);}
100% {transform: scale(1);}
}
@keyframes zoomOut {
0% {transform: scale(1);}
100% {transform: scale(0.9);}
}