Home > Net >  Loop through items and after set interval remove class from all whilst adding class to next item
Loop through items and after set interval remove class from all whilst adding class to next item

Time:06-16

I have built a simple carousel which fades in/out of various images. The visual changes happen in CSS when JS changes the class.

This worked perfectly with two slides. Now I've introduced a third it does not and I can now see why it worked with 2 and doesn't with 3 or more.

Essentially what I'd like to achieve is this:

Every 7 seconds the script removes all instances of slide--active and adds it to the next item in the loop.

I'm using Jquery throughout the site, so it makes sense to utilise it. The CSS below can be ignored, I'm only interested in the class change.

$('.slides').each(function(i, item) {
    setInterval(
        function() {
          $('.slide').toggleClass('slide--active');
        },
    7000   i)
});
.slide { 
  width: 4em; 
  height: 4em;
  background: blue;
}
.slide--active { 
  background: red; 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul >
    <li ></li>
    <li ></li>
    <li ></li>
</ul>

CodePudding user response:

You can do it like this:

setInterval(
  function() {
    var item = $(".slide--active");
    var next = item.next(".slide").length == 0 ? $('.slide').first() : item.next(".slide")
    item.removeClass("slide--active");
    next.toggleClass('slide--active');
  },
  2000)

This will remove the active class from the current element, and set the active class on the next element (or first element if current element is last)

Demo

setInterval(
  function() {
    var item = $(".slide--active");
    var next = item.next(".slide").length == 0 ? $('.slide').first() : item.next(".slide")
    item.removeClass("slide--active");
    next.toggleClass('slide--active');
  },
  2000)
.slide {
  width: 4em;
  height: 4em;
  background: blue;
}

.slide--active {
  background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul >
  <li ></li>
  <li ></li>
  <li ></li>
</ul>

CodePudding user response:

As I explained in the comments, you should only toggle the current and the next slide. Finally reset to the first slide when the last slide is done.

// Get the number of slides
let totalSlides = $('.slides .slide').length;

setInterval(function(){
  let current = false;
  $('.slide').each(function(i, item) {
    if(!current){
      if(item.classList.contains('slide--active')){
      
        if(i === totalSlides - 1)
        {
          $('.slide:first-child').addClass('slide--active');
        }
        item.classList.toggle('slide--active');
        current = true;
      }
    } else {
      item.classList.toggle('slide--active');
      current = false;
      return false;
    }
  });
}, 7000);
.slide { 
  width: 4em; 
  height: 4em;
  background: blue;
}
.slide--active { 
  background: red; 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul >
    <li ></li>
    <li ></li>
    <li ></li>
</ul>

CodePudding user response:

let currentIndex = 0;

const slides = $('.slide');
const numberOfSlides = slides.length;

setInterval(() => {

  // Find next item index
  currentIndex = ((currentIndex   1) % numberOfSlides);

  // Remove class from all slides
  slides.removeClass('slide--active');

  // Add class to a next item
  slides.eq(currentIndex).addClass('slide--active')

}, 7000)

Or you can track previous index and just remove class from previous slide.

  • Related