Scrollbar with buttons

by namlth

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.3/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css">



<div class="d-flex flex-nowrap justify-content-center align-items-center my-5">
  <div class="order-1">
    <i id="scrollLeft" class="btn-font-awesome fas fa-angle-left display-3"></i>
  </div>
  <div class="order-3">
    <i id="scrollRight" class="btn-font-awesome fas fa-angle-right display-3"></i>
  </div>
  <div class="progress-box order-2">
    <div class="step-box bg-danger">1</div>
    <div class="step-box bg-info">2</div>
    <div class="step-box bg-secondary">3</div>
    <div class="step-box bg-success">4</div>
    <div class="step-box bg-danger">5</div>
    <div class="step-box bg-info">6</div>
    <div class="step-box bg-secondary">7</div>
    <div class="step-box bg-success">8</div>
    <div class="step-box bg-danger">9</div>
    <div class="step-box bg-info">10</div>
    <div class="step-box bg-secondary">11</div>
    <div class="step-box bg-success">12</div>
  </div>
</div>
<div class="show-scroll"></div>

SCSS

#test {
  width: 100px;
  height: 100px;
  background: green;
  position: relative;
  left: 1000px;
}

.progress-box {
  width: 100%;
  height: 100px;
  background: lightblue;
  overflow-x: scroll;
  -webkit-overflow-scrolling: touch;
  display: flex;
  justify-content: space-between;
  align-items: center;
  &::-webkit-scrollbar {
    display: none;
  }
}

.step-box {
  width: 100%;
  min-width: 25%;
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  color: white;
  font-size: 2rem;
}

.btn-font-awesome {
  color: transparent;
   -webkit-text-stroke-width: 2px;
   -webkit-text-stroke-color: #3A75C4;
}

JavaScript

(function(elmProto){
  if ('scrollTopMax' in elmProto) {
    return;
  }
  Object.defineProperties(elmProto, {
    'scrollTopMax': {
      get: function scrollTopMax() {
        return this.scrollHeight - this.clientHeight;
      }
    },
    'scrollLeftMax': {
      get: function scrollLeftMax() {
        return this.scrollWidth - this.clientWidth;
      }
    }
  });
}
)(Element.prototype);

var scrollDuration = 400;
var boxScrollRange = 200;
var isClicking = false;

$('#scrollRight').click(function() {
  if (isClicking === true) return;

  isClicking = true;

  boxScrollRange = $('.progress-box').scrollLeft() + $(".step-box").width() * 2;

  if (boxScrollRange + $('.progress-box')[0].scrollLeftMax % $(".step-box").width() === $('.progress-box')[0].scrollLeftMax) {
    boxScrollRange = $('.progress-box')[0].scrollLeftMax;
  }

  if ($('.progress-box').scrollLeft() < $('.progress-box')[0].scrollLeftMax) {
    $('.progress-box').animate(
      {
        scrollLeft: boxScrollRange
      }, 
      {
        duration: scrollDuration,
        complete: () => {
          $(".show-scroll").html("scrollLeft " + $('.progress-box').scrollLeft() + " scrollLeftMax: " + $('.progress-box')[0].scrollLeftMax + " step width: " + $(".step-box").width());
          isClicking = false;
        }
      });
  }
  else isClicking = false;
});

$('#scrollLeft').click(function() {
  if (isClicking === true) return;

  isClicking = true;

  if ($('.progress-box').scrollLeft() === $('.progress-box')[0].scrollLeftMax) {
    boxScrollRange = $('.progress-box').scrollLeft() - $('.progress-box')[0].scrollLeftMax % $(".step-box").width() - ($(".step-box").width() * 2);
  }
  else {
    boxScrollRange = $('.progress-box').scrollLeft() - ($(".step-box").width() * 2);
  }

  if ($('.progress-box').scrollLeft() > 0) {
    $('.progress-box').animate(
      {
        scrollLeft: boxScrollRange
      }, 
      {
        duration: scrollDuration,
        complete: () => {
         ...