Convert this slide to a loop?

Issue

I made a div slider with arrows, each div is set to a min-width of 60px.

The code works just fine, except, when I navigate with the arrow either to the left or to the right, it stops at the last item. I want it to loop (as in endlessly). Instead of stopping at the last item.

let rightArrow = document.getElementById('right')
rightArrow.onclick = function() {
  let container = document.getElementById('box')
  sideScroll(container, 'right', 25, 80, 10)
}

let leftArrow = document.getElementById('left')
leftArrow.onclick = function() {
  let container = document.getElementById('box')
  sideScroll(container, 'left', 25, 80, 10)
}

function sideScroll(element, direction, speed, distance, step) {
  // body...
  scrollAmount = 0

  let slideTimer = setInterval(function() {
    // body...
    if (direction == 'left') {
      element.scrollLeft -= step
    } else {
      element.scrollLeft += step
    }

    scrollAmount += step

    if (scrollAmount >= distance) {
      window.clearInterval(slideTimer)
    }
  }, speed)
}
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  background-color: #efefef;
  width: 100%;
  height: 100vh;
  background-image: radial-gradient(circle, #2196f3, #3f51b5);
  font-family: 'Nirmala UI';
  display: grid;
  place-items: center;
}

div.main {
  position: relative;
  background-color: #fff;
  border-radius: 10px;
}

div.main div.item_div {
  width: 300px;
  overflow: auto;
  display: flex;
}

div.main div.item_div::-webkit-scrollbar {
  display: none;
}

div.main div.item_div div.item {
  min-width: 60px;
  min-height: 60px;
  border-radius: 10px;
  background-color: grey;
  display: grid;
  place-items: center;
  font-size: 40px;
  text-transform: uppercase;
  scroll-behavior: smooth;
  user-select: none;
}

div.main div.item_div div.item:not(:last-child) {
  margin-right: 20px;
}

div.arrow {
  position: absolute;
  width: 40px;
  height: 40px;
  background-color: #f0f0f0;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  top: 50%;
  transform: translateY(-50%);
}

div#left {
  left: -60px;
}

div#right {
  right: -60px;
}

div.arrow span {
  font-size: 20px;
  user-select: none;
}

div.arrow:hover {
  cursor: pointer;
}
<div class="main">
  <div class="item_div" id="box">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
    <div class="item">6</div>
    <div class="item">7</div>
    <div class="item">8</div>
    <div class="item">9</div>
    <div class="item">10</div>
  </div>
  <div class="arrow" id="left"><span>&#10094;</span></div>
  <div class="arrow" id="right"><span>&#10095;</span></div>
</div>

Can anyone help me out? Please?

Solution

You can you scrollLeft to check the position of scrollbar and move the bar to the start or end accordingly.

I have highlighted the changes I made to the code using comments

let rightArrow = document.getElementById('right')
rightArrow.onclick = function() {
  let container = document.getElementById('box')
  //check if the scrollbar is located at the end and reset it to starting position
  if (container.scrollLeft == container.scrollWidth - container.offsetWidth) {
    container.scrollLeft = 0;     
  } else {
     sideScroll(container, 'right', 25, 80, 10)
  }
  
}

let leftArrow = document.getElementById('left')
leftArrow.onclick = function() {
  let container = document.getElementById('box')
  //check if the scrollbar is located at the start and reset it to ending position
  if (container.scrollLeft == 0) {
      container.scrollLeft = container.scrollWidth;
  } else {
      sideScroll(container, 'left', 25, 80, 10)
  }
  
}

function sideScroll(element, direction, speed, distance, step) {
  // body...
  scrollAmount = 0
  

  let slideTimer = setInterval(function() {
    // body...
    if (direction == 'left') {
      element.scrollLeft -= step
    } else {
      element.scrollLeft += step
    }
    
    

    scrollAmount += step
    
    

    if (scrollAmount >= distance) {
      window.clearInterval(slideTimer)
    }
  }, speed)
  
  
}
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  background-color: #efefef;
  width: 100%;
  height: 100vh;
  background-image: radial-gradient(circle, #2196f3, #3f51b5);
  font-family: 'Nirmala UI';
  display: grid;
  place-items: center;
}

div.main {
  position: relative;
  background-color: #fff;
  border-radius: 10px;
}

div.main div.item_div {
  width: 300px;
  overflow: auto;
  display: flex;
}

div.main div.item_div::-webkit-scrollbar {
  display: none;
}

div.main div.item_div div.item {
  min-width: 60px;
  min-height: 60px;
  border-radius: 10px;
  background-color: grey;
  display: grid;
  place-items: center;
  font-size: 40px;
  text-transform: uppercase;
  scroll-behavior: smooth;
  user-select: none;
}

div.main div.item_div div.item:not(:last-child) {
  margin-right: 20px;
}

div.arrow {
  position: absolute;
  width: 40px;
  height: 40px;
  background-color: #f0f0f0;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  top: 50%;
  transform: translateY(-50%);
}

div#left {
  left: -60px;
}

div#right {
  right: -60px;
}

div.arrow span {
  font-size: 20px;
  user-select: none;
}

div.arrow:hover {
  cursor: pointer;
}
<div class="main">
  <div class="item_div" id="box">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
    <div class="item">6</div>
    <div class="item">7</div>
    <div class="item">8</div>
    <div class="item">9</div>
    <div class="item">10</div>
  </div>
  <div class="arrow" id="left"><span>&#10094;</span></div>
  <div class="arrow" id="right"><span>&#10095;</span></div>
</div>

Answered By – Mani

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published