技术频道导航
HTML/CSS
.NET技术
IIS技术
PHP技术
Js/JQuery
Photoshop
Fireworks
服务器技术
操作系统
网站运营

赞助商

分类目录

赞助商

最新文章

搜索

CSS+JS: 提交按钮点击后变为执行中动画,完成后再变成提交按钮

作者:admin    时间:2022-9-12 11:14:18    浏览:

在网页交互中经常看见这样的效果,就是点击提交按钮后,提交按钮变为执行中动画,当执行完成,再变为提交按钮。这样设计的好处是让用户清楚知道执行动作正在进行中,请等待一会。

demodownload

本文将通过CSS+JS来实现这一效果。

实现代码

HTML

<button class="btn" type="button">
<span class="btn__text">Submit</span>
<svg class="btn__progress" viewBox="0 0 48 48" width="48px" height="48px">
<circle class="btn__progress-track" r="20" cx="24" cy="24" fill="none" stroke="#c7cad1" stroke-width="8" />
<circle class="btn__progress-fill" r="20" cx="24" cy="24" fill="none" stroke="#000000" stroke-width="8" transform="rotate(-90,24,24)" stroke-dasharray="125.66 125.66" stroke-dashoffset="125.66" />
<polyline class="btn__progress-check" points="12,24 20,32 36,16" fill="none" stroke="#fff" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="34 34" stroke-dashoffset="34" />
</svg>
</button>

CSS

* {
  border: 0;
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

:root {
  --hue: 223;
  --bg1: hsl(var(--hue),10%,90%);
  --bg2: hsl(var(--hue),10%,80%);
  --fg1: hsl(var(--hue),10%,10%);
  --fg2: hsl(var(--hue),10%,20%);
  --primary1: hsl(var(--hue),90%,55%);
  --primary2: hsl(var(--hue),90%,45%);
  font-size: calc(20px + (40 - 20) * (100vw - 320px) / (1280 - 320));
}

body, button {
  font: 1em/1.5 Nunito, sans-serif;
}

body {
  background-color: var(--bg1);
  color: var(--fg1);
  height: 100vh;
  display: grid;
  place-items: center;
}

/* Main button styles */
.btn {
  background-color: transparent;
  border-radius: 1.5em;
  display: block;
  position: relative;
  width: 7.5em;
  height: 3em;
  transition: width 0.3s ease-in-out;
}

.btn:not(:disabled):active {
  transform: translateY(0.1em);
}

.btn__text {
  background-color: var(--primary1);
  border-radius: inherit;
  color: hsl(0,0%,100%);
  display: inline-block;
  padding: 0.75em 1.5em;
  transition: background-color 0.15s linear,
color 0.15s 0.3s ease-in-out;
  width: 100%;
}

.btn:not(:disabled):focus .btn__text,
.btn:not(:disabled):hover .btn__text {
  background-color: var(--primary2);
}

.btn__progress {
  overflow: visible;
  position: absolute;
  top: 0;
  left: 0;
  width: 3em;
  height: 3em;
  visibility: hidden;
}

.btn__progress-track {
  r: 12px;
  stroke: var(--bg2);
  stroke-width: 24;
}

.btn__progress-fill {
  stroke: var(--primary1);
  stroke-dashoffset: 125.66;
}

.btn__progress-check {
  stroke: hsl(0,0%,100%);
  stroke-dashoffset: 34;
}

/* Both states */
.btn--running,
.btn--done {
  outline: none;
  pointer-events: none;
  width: 3em;
  user-select: none;
  -moz-user-select: none;
  -webkit-user-select: none;
}

.btn--running .btn__text,
.btn--done .btn__text {
  color: transparent;
  transition: background-color 0.3s ease-in-out,
visibility 0.3s steps(1);
}

.btn--running .btn__progress,
.btn--done .btn__progress {
  visibility: visible;
}

/* Running state */
.btn--running .btn__text {
  background-color: var(--bg2);
  visibility: hidden;
}

.btn--running .btn__progress {
  transition: visibility 0.3s 0.3s steps(1,start);
}

.btn--running .btn__progress-track {
  r: 20px;
  stroke-width: 8;
  transition: r 0.3s 0.3s ease-in-out,
stroke-width 0.3s 0.3s ease-in-out;
}

.btn--running .btn__progress-fill {
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 2s 0.6s linear;
}

/* Done state */
.btn--done .btn__progress-track {
  stroke: var(--primary1);
  transition: r 0.3s ease-in-out,
stroke-width 0.3s ease-in-out;
}

.btn--done .btn__progress-check {
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 0.3s 0.3s ease-out;
}

/* Dark theme */
@media (prefers-color-scheme: dark) {
  :root {
    --bg1: hsl(var(--hue),10%,10%);
    --bg2: hsl(var(--hue),10%,20%);
    --fg1: hsl(var(--hue),10%,90%);
    --fg2: hsl(var(--hue),10%,80%);
  }
}

JavaScript

window.addEventListener("DOMContentLoaded", () =>
{
  const btn = document.querySelector("button");
  var doneTimeout = null,
    resetTimeout = null;
  if (btn)
  {
    btn.addEventListener("click", function()
    {
      const runClass = "btn--running";
      const doneClass = "btn--done";
      // `.btn--running .btn__progress-fill` `stroke-dashoffset` duration in ms
      const submitDuration = 2000;
      const resetDuration = 1500;
      // fake the submission
      this.disabled = true;
      this.classList.add(runClass);
      clearTimeout(doneTimeout);
      clearTimeout(resetTimeout);
      doneTimeout = setTimeout(() =>
      {
        this.classList.remove(runClass);
        this.classList.add(doneClass);
        // reset the button
        resetTimeout = setTimeout(() =>
        {
          this.disabled = false;
          this.classList.remove(doneClass);
        }, resetDuration);
      }, 600 + submitDuration);
    });
  }
});

相关文章

标签: 提交按钮  按钮  
x
x
  • 站长推荐