这个示例展示了如何实现一个平滑滚动的进度条。
我们从一个初始状态开始,其中有一个按钮,它向 /start 发送 POST 请求来开始任务:
<div hx-target="this" hx-swap="outerHTML">
<h3>开始进度</h3>
<button class="btn primary" hx-post="/start">
开始任务
</button>
</div>
这个 div 随后被替换为一个包含状态和进度条的新 div,该进度条每 600ms 重新加载自身:
<div hx-trigger="done" hx-get="/job" hx-swap="outerHTML" hx-target="this">
<h3 role="status" id="pblabel" tabindex="-1" autofocus>运行中</h3>
<div
hx-get="/job/progress"
hx-trigger="every 600ms"
hx-target="this"
hx-swap="innerHTML">
<div class="progress" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0" aria-labelledby="pblabel">
<div id="pb" class="progress-bar" style="width:0%">
</div>
</div>
</div>
这个进度条每 600 毫秒更新一次,“width” 样式属性和 aria-valuenow 属性设置为当前进度值。
由于进度条 div 上有一个 id,htmx 将在请求之间平滑过渡,通过将样式属性平滑过渡到其新值。这与 CSS 过渡结合使用时,会使视觉过渡连续而不是跳跃式的。
最后,当进程完成时,服务器返回 HX-Trigger: done 头,这会触发 UI 更新到“完成”状态,并向 UI 添加一个重新启动按钮(在本示例中,我们使用 class-tools 扩展为按钮添加淡入效果):
<div hx-trigger="done" hx-get="/job" hx-swap="outerHTML" hx-target="this">
<h3 role="status" id="pblabel" tabindex="-1" autofocus>完成</h3>
<div
hx-get="/job/progress"
hx-trigger="none"
hx-target="this"
hx-swap="innerHTML">
<div class="progress" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="122" aria-labelledby="pblabel">
<div id="pb" class="progress-bar" style="width:122%">
</div>
</div>
</div>
<button id="restart-btn" class="btn primary" hx-post="/start" classes="add show:600ms">
重新启动任务
</button>
</div>
这个示例使用了从 bootstrap 进度条中借鉴的样式:
.progress {
height: 20px;
margin-bottom: 20px;
overflow: hidden;
background-color: #f5f5f5;
border-radius: 4px;
box-shadow: inset 0 1px 2px rgba(0,0,0,.1);
}
.progress-bar {
float: left;
width: 0%;
height: 100%;
font-size: 12px;
line-height: 20px;
color: #fff;
text-align: center;
background-color: #337ab7;
-webkit-box-shadow: inset 0 -1px 0 rgba(0,0,0,.15);
box-shadow: inset 0 -1px 0 rgba(0,0,0,.15);
-webkit-transition: width .6s ease;
-o-transition: width .6s ease;
transition: width .6s ease;
}