DEV Community

Cover image for Make A Progress Bar with JavaScript
Amy Oulton
Amy Oulton

Posted on

Make A Progress Bar with JavaScript

This tutorial was originally posted on CodeCast. There you can watch my tutorial while accessing all the live code I am writing in the video using their interactive player.

Hello! We're back with another JavaScript tutorial and this time we're going to make a simple progress bar.

Progress Bar Gif

As per always, we are going to create the structure of our app first by building out the HTML. This will look as follows:

 <div class="container">
   <div id="progress">
     <div id="bar">1%</div>
   </div>
   <button class="btn">Run Bar</button>
 </div>
Enter fullscreen mode Exit fullscreen mode

If you're not interested in having the physical number within the progress bar, go ahead and delete the 1% inside the #bar div, but make sure to keep the div as it is, as that is the actual progress bar.

Next we go ahead and add some styles to the page, which you can find in the tutorial above! We also need to add styles to control the width of the bar, so for now we'll see the default width to be 1%.

 #bar {
   width: 1%;
   height: 30px;
   background-color: magenta;
   color: white;
   font-weight: bold;
 }
Enter fullscreen mode Exit fullscreen mode

The first thing we're going to do is the access the button on the page and add an event to listen for any clicks.

  document.querySelector('.btn').addEventListener('click', 
  moveBar);
Enter fullscreen mode Exit fullscreen mode

You can see above that we have assigned the moveBar variable to be triggered when the user clicks, so now we need to go ahead and build that function out.

Firstly, we will declare the function, and the assign the bar variable to be the div with the id of bar.

  const moveBar = () => {
    const bar = document.getElementById('bar');
  };
Enter fullscreen mode Exit fullscreen mode

From there we also need to set a standard width for our bar. Since we started it at 1% in our styles, we we're going to set it to the same inside of our function as follows:

 const moveBar = () => {
   const bar = document.getElementById('bar');
   let width = 1;
 };
Enter fullscreen mode Exit fullscreen mode

This default width can be anything you want. Many would prefer to start it at 0 so it doesn't show up at all in the beginning, but for the sake of the tutorial I chose to start it at 1% so we could see it.

Next, we're going to get started on controlling the progress bar. Because we want out bar to slowly load, we are going to make use of the setInterval() built-in method.

 const moveBar = () => {
   const bar = document.getElementById('bar');
   let width = 1;

   setInterval(rate, 30);
 };
Enter fullscreen mode Exit fullscreen mode

Within that setInterval(), you can see we're asking it to run rate ever 30 milliseconds. However, rate doesn't exist yet, so lets go ahead and build that out.

  const moveBar = () => {
    const bar = document.getElementById('bar');
    let width = 1;

    const rate = () => {
      width++;
      bar.style.width = `${width}%`;
    };

   setInterval(rate, 30);
  };
Enter fullscreen mode Exit fullscreen mode

What we have done above works as follows: every time rate is wrong, it adds 1 to width. It then access the width style property, and reassigns it the new value of width.

However, there is still one very crucial step we're missing. Whenever we call setInterval(), it will run until we clear it. As our function is currently written, there is nothing tell the bar to stop, so even though we want the bar to stop progressing at 100%, the code doesn't know that. So let's tell it.

We do this by updating the rate function as follows:

  const rate = () => {
    if (width >= 100) {
      clearInterval(interval);
    } else {
      width++;
      bar.style.width = `${width}%`;
    }
  };
Enter fullscreen mode Exit fullscreen mode

Now, once width hits 100, The interval is being cleared, stopping the width from updating and ceasing the progress bar.

We don't want to reset the progress bar here because we want the view to remain 100% until they run the bar again. Since we have that initial, 1 value assigned to our width variable, it will reset that bar to 1% once the user clicks the button.

So there you have it. An incredible simple progress bar. There are an endless amount of things you can do to improve this bar. You can add dynamic information so that the progress bar updates every time a promise is met during a fetch request, or do something simpler like add "pause" button.

Your Challenge

I want to see how you can improve upon this simple progress bar. Whether it's style improvements, refactoring my code, or adding additional features, record a cast on CodeCast, then leave the URL down below. 👇🏻

Happy coding! 💻

Discussion (2)

Collapse
jonrandy profile image
Jon Randy • Edited

You're probably better off using the <progress> element - css-tricks.com/html5-progress-elem...

Collapse
amyoulton profile image
Amy Oulton Author

oh fantastic, i'll look into this!