Matt Don
Matt Don

Reputation: 71

Make these slides loop?

I have been working on this for a little while, and I think I'm stuck at this point.

I made a div slider with arrows. Each div slide is set to a min-width of 80px.

The code works just fine, except, when I navigate either to the left or the right, it stops at the last item. I want this slider to loop (as in endlessly), instead of ending at the last item.

let buttonLeft = document.getElementById('slide_left')
    let buttonRight = document.getElementById('slide_right')

    buttonLeft.addEventListener('click', function() {
        document.getElementById('slider').scrollLeft -= 90
    })

    buttonRight.addEventListener('click', function() {
        document.getElementById('slider').scrollLeft += 90
    })
body{
            background-color: #555;
            height: 100vh;
            display: grid;
            align-items: center;
            justify-items: center;
            font-family: 'Helvetica';
        }
        
        div#slide_wrapper{
            width: 440px;
            display: flex;
            justify-content: space-between;
            height: fit-content;
        }
        
        div#slider{
            width: 350px;
            display: flex;
            height: fit-content;
            flex-wrap: nowrap;
            overflow: hidden;
        }
        
        div.thumbnail{
            min-width: 80px;
            min-height: 80px;
            cursor: pointer;
            display: grid;
            place-items: center;
            font-size: 30px;
        }

        div.thumbnail:not(:last-child){
            margin-right: 10px;
        }

        div.thumbnail:nth-child(1){
            background-color: darkturquoise;
        }
        div.thumbnail:nth-child(2){
            background-color: goldenrod;
        }
        div.thumbnail:nth-child(3){
            background-color: rebeccapurple;
        }
        div.thumbnail:nth-child(4){
            background-color: powderblue;
        }
        div.thumbnail:nth-child(5){
            background-color: firebrick;
        }
        div.thumbnail:nth-child(6){
            background-color: sienna;
        }
        div.thumbnail:nth-child(7){
            background-color: bisque;
        }
        div.thumbnail:nth-child(8){
            background-color: navy;
        }
        
        div#slide_wrapper > button{
            height: fit-content;
            align-self: center;
            font-size: 24px;
            font-weight: 800;
            border: none;
            outline: none;
        }
        
        div#slide_wrapper > button:hover{
            cursor: pointer;
            background-color: dodgerblue;
            color: #fff;
        }
<div id="slide_wrapper">
        <button id="slide_left" class="slide_arrow">&#10094;</button>
        <div id="slider">
            <div class="thumbnail active">1</div>
            <div class="thumbnail">2</div>
            <div class="thumbnail">3</div>
            <div class="thumbnail">4</div>
            <div class="thumbnail">5</div>
            <div class="thumbnail">6</div>
            <div class="thumbnail">7</div>
            <div class="thumbnail">8</div>
        </div>
        <button id="slide_right" class="slide_arrow">&#10095;</button>
    </div>

Upvotes: 2

Views: 102

Answers (2)

Maik Lowrey
Maik Lowrey

Reputation: 17556

Nice slider! There are several ways to achieve what you want. In my opinion, the simplest solution would be to work with some if conditions and a counter variable. Once the number of thumbnails is reached, set the counter back to 0.

Update

Regarding to your comment. "How about doing the same for the left arrow.". In the if condition block: if (0 == slideCount) { i add these lines:

    slideCount = thumbnail.length // set the slideCounter to maximum
    document.getElementById('slider').scrollLeft = slideCount * 90 // calculate the scroll distance
    slideCount--; // decrease slidecount
    setActive();  // set the red border on the current slide

const buttonLeft = document.getElementById('slide_left')
const  buttonRight = document.getElementById('slide_right')
const thumbnail = document.querySelectorAll(".thumbnail");
let slideCount = 0;
setActive();

buttonLeft.addEventListener('click', function() {
  if (0 == slideCount) {
    slideCount = thumbnail.length
    document.getElementById('slider').scrollLeft = slideCount * 90
    slideCount--;
    setActive();    
    return;
  }
  slideCount--;
  document.getElementById('slider').scrollLeft -= 90  
  setActive();
})

buttonRight.addEventListener('click', function() {
  slideCount++;
  if ( 8  ==  slideCount) {    
    document.getElementById('slider').scrollLeft = 0
    slideCount = 0;
  } else {
    document.getElementById('slider').scrollLeft += 90  
  }    
  setActive();
})

function setActive() {  
  thumbnail.forEach(t => {
    t.classList.remove("active");
  })
  thumbnail[slideCount].classList.add("active")
}


function count() {
  console.log(slideCount);
}
body{
  background-color: #555;
  height: 100vh;
  display: grid;
  align-items: center;
  justify-items: center;
  font-family: 'Helvetica';
}

div#slide_wrapper{
  width: 440px;
  display: flex;
  justify-content: space-between;
  height: fit-content;
}

div#slider{
  width: 350px;
  display: flex;
  height: fit-content;
  flex-wrap: nowrap;
  overflow: hidden;
}

div.thumbnail{
  min-width: 80px;
  min-height: 80px;
  cursor: pointer;
  display: grid;
  place-items: center;
  font-size: 30px;
}

div.thumbnail:not(:last-child){
  margin-right: 10px;
}

div.thumbnail:nth-child(1){
  background-color: darkturquoise;
}
div.thumbnail:nth-child(2){
  background-color: goldenrod;
}
div.thumbnail:nth-child(3){
  background-color: rebeccapurple;
}
div.thumbnail:nth-child(4){
  background-color: powderblue;
}
div.thumbnail:nth-child(5){
  background-color: firebrick;
}
div.thumbnail:nth-child(6){
  background-color: sienna;
}
div.thumbnail:nth-child(7){
  background-color: bisque;
}
div.thumbnail:nth-child(8){
  background-color: navy;
}

div#slide_wrapper > button{
  height: fit-content;
  align-self: center;
  font-size: 24px;
  font-weight: 800;
  border: none;
  outline: none;
}

div#slide_wrapper > button:hover{
  cursor: pointer;
  background-color: dodgerblue;
  color: #fff;
}

.active {
  border: 2px solid red;
}
<div id="slide_wrapper">
  <button id="slide_left" class="slide_arrow">&#10094;</button>
  <div id="slider">
    <div class="thumbnail active">1</div>
    <div class="thumbnail">2</div>
    <div class="thumbnail">3</div>
    <div class="thumbnail">4</div>
    <div class="thumbnail">5</div>
    <div class="thumbnail">6</div>
    <div class="thumbnail">7</div>
    <div class="thumbnail">8</div>
  </div>
  <button id="slide_right" class="slide_arrow">&#10095;</button>
</div>

Upvotes: 2

Faizal Hussain
Faizal Hussain

Reputation: 1581

Just find the width of the slider and compare it with the scroll left like

 let buttonLeft = document.getElementById('slide_left')
let buttonRight = document.getElementById('slide_right')

buttonLeft.addEventListener('click', function() {
    document.getElementById('slider').scrollLeft -= 90
})

buttonRight.addEventListener('click', function() {

  const elem = document.getElementById('slider');
  
  const ElemWidth = elem.getClientRects()[0].width
 
  
   
  
 if(document.getElementById('slider').scrollLeft > ElemWidth ){
    document.getElementById('slider').scrollLeft = 0
 }else{
   document.getElementById('slider').scrollLeft += 90 
 }
  
   console.log(ElemWidth,  document.getElementById('slider').scrollLeft , document.getElementById('slider').scrollLeft > ElemWidth)
})

Upvotes: 0

Related Questions