skip to Main Content

I would like to create an image carousel using plain JavaScript and HTML. I have been able to move to the next slide with the logic I have but having trouble with the previous slide functionality. When going through the next slide the slideshow at the end restarts at the first picture. I would also like to have this behaviour with the previous slide functionality going to the last picture instead of receiving a Uncaught TypeError.

How can I achieve this ?

const container = document.querySelector(".div-container")
const nextBtn = document.querySelector(".next")
const prevBtn = document.querySelector(".previous")
let currentIndex = 0;

const nextSlide = () => {
  const slides = document.getElementsByClassName("slide")
  for (let i = 0; i < slides.length; i++) {
    slides[i].style.display = "none"
  }
  currentIndex++
  if (currentIndex > slides.length) {
    currentIndex = 1
  }
  slides[currentIndex - 1].style.display = "block"
}

nextSlide()

const prevSlide = () => {
  const slides = document.getElementsByClassName("slide")
  for (let i = 0; i < slides.length; i++) {
    slides[i].style.display = "none"
  }
  currentIndex--
  slides[currentIndex - 1].style.display = "block"
}

nextBtn.addEventListener("click", () => {
  nextSlide()
})

prevBtn.addEventListener("click", () => {
  prevSlide()
})
.div-container {
  display: flex;
  justify-content: center;
  max-width: 1000px;
}

.slide {
  display: none;
}

.image {
  width: 300px;
}
<body>
  <div class="div-container">
    <button class="previous">Previous</button>
    <div class="slide fade">
      <img src="https://i.redd.it/z7myrlhfhxr31.jpg" alt="windows xp autumn" class="image">
    </div>
    <div class="slide fade">
      <img src="https://www.newegg.com/insider/wp-content/uploads/windows_xp_bliss-wide.jpg" alt="windows xp bliss" class="image">
    </div>
    <div class="slide fade">
      <img src="https://i0.wp.com/tjkelly.com/wp-content/uploads/windows-xp-desktop-background-wallpaper-follow-800x600.jpg?ssl=1" alt="windows xp fishy" class="image">
    </div>
    <button class="next">Next</button>
  </div>
</body>

2

Answers


  1. I fixed your code with as little changes as possible. Instead of two separate functions I am now using just one for stepping forward and backward:

    const container = document.querySelector(".div-container")
    const nextBtn = document.querySelector(".next")
    const prevBtn = document.querySelector(".previous")
    let currentIndex = 0;
    
    const nextSlide = (inc) => {
      const slides = document.getElementsByClassName("slide")
      for (let i = 0; i < slides.length; i++) {
        slides[i].style.display = "none"
      }
      currentIndex=(currentIndex+slides.length+inc)%slides.length;
      slides[currentIndex].style.display = "block"
    }
    
    nextSlide(0)
    
    nextBtn.addEventListener("click", () => {
      nextSlide(1)
    })
    
    prevBtn.addEventListener("click", () => {
      nextSlide(-1)
    })
    .div-container {
      display: flex;
      justify-content: center;
      max-width: 1000px;
    }
    
    .slide {
      display: none;
    }
    
    .image {
      width: 300px;
    }
    <body>
      <div class="div-container">
        <button class="previous">Previous</button>
        <div class="slide fade">
          <img src="https://i.redd.it/z7myrlhfhxr31.jpg" alt="windows xp autumn" class="image">
        </div>
        <div class="slide fade">
          <img src="https://www.newegg.com/insider/wp-content/uploads/windows_xp_bliss-wide.jpg" alt="windows xp bliss" class="image">
        </div>
        <div class="slide fade">
          <img src="https://i0.wp.com/tjkelly.com/wp-content/uploads/windows-xp-desktop-background-wallpaper-follow-800x600.jpg?ssl=1" alt="windows xp fishy" class="image">
        </div>
        <button class="next">Next</button>
      </div>
    </body>

    The central part of the operation is the expression

    currentIndex=(currentIndex+slides.length+inc)%slides.length
    

    It calculates a new currentIndex by adding inc to the current value. inc can be -1, 0 or 1 and the resulting value will always be between 0 and slides.length-1.

    There is scope for further improvements (code simplification and reduction of global variables), but that is a separate issue.

    Login or Signup to reply.
  2. Just check in prevSlide function if currentIndex is zero and set it to slides.length:

     currentIndex--
    if (currentIndex === 0) {
     currentIndex = slides.length
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search