Step by step script

Sometimes you need to slow things down to provide visual feedback to the user. Here's how to create a step by step script.

HTML

<div class="steps">
  <span id="step">0</span>/3
  <div class="progress">
    <div id="progressBar" class="progress-bar"></div>
  </div>
  <button id="start">Start</button>
</div>
<div class="result">
  <b>Result : </b><span id="result">waiting start</span>
</div>

CSS

body {
  padding: 1em;
  font-family: sans-serif;
  color: #333;
  text-align: center;
}

button,
.progress {
  margin: 1em 0;
}

.progress {
  position: relative;
  width: 100%;
  height: 1em;
  background: #CCC;
  border-radius: 1em;
}

.progress-bar {
  position: absolute;
  top: 0;
  left: 0;
  width: 0;
  height: 1em;
  background: #2ABB9B;
  border-radius: 1em;
  transition: all 1s linear;
}

JavaScript

var $start = document.getElementById('start')
var $step = document.getElementById('step')
var $result = document.getElementById('result')
var $progressBar = document.getElementById('progressBar')

// Delay next step by passing function as a callback with an undefined number of arguments
function nextStep(cb, ...args) {
  setTimeout(() => {
    cb(...args)
  }, 1000)
}

function step1(foo) {
  // update current step
  $progressBar.style.width = '66%';
  $step.innerHTML = '1'
  // some logic and pass result to next step
  var bar = foo * 2
  nextStep(step2, foo, bar)
}

function step2(foo, bar) {
  // update current step
  $progressBar.style.width = '100%';
  $step.innerHTML = '2'
  // some logic and pass result to next step
  var foobar = (foo + bar) * 2
  nextStep(step3, foo, bar, foobar)
}

function step3(foo, bar, foobar) {
  // update current step
  $progressBar.style.width = '100%';
  $step.innerHTML = '3'
  // some logic and pass result to next step
  $result.innerHTML = foo + bar + foobar
}

function start() {
  // update current step
  $progressBar.style.width = '33%';
  $result.innerHTML = 'waiting...'
  nextStep(step1, 2)
}

$start.onclick = start;