toogle class of list of elements sequentially infinitely

Viewed 26

I have a series of div elements that I want to show and hide sequentially using toggleClass. My code works like a charm.

I would now like to go back to the first div when the last div is active, and so on infinitely. I can't figure out how to do this.

var timeout = 2000
setTimeout(function() {
  $(".text-sequence .text").each(function(i, el) {
    var $this = $(this);
    setTimeout(function() {
      $this.toggleClass('active')
      $(".text-sequence .text").not($this).removeClass('active')
    }, i * timeout)
  })
}, timeout)
.text {
  opacity: 0
}

.text.active {
  opacity: 1
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="text-sequence">
  <div class="text">Text 1</div>
  <div class="text">Text 2</div>
  <div class="text">Text 3</div>
  <div class="text">Text 4</div>
  <div class="text">Text 5</div>
  <div class="text">Text 6</div>
</div>

2 Answers

Your code is a bit more complex than necessary. You don't need to wrap an interval in a timeout, and you don't need the loop within that timeout.

To do what you require simply target the current .active element and use next() to get the next element. You can determine if there is no next element and then go back to the first() again.

Note in the following example that I shortened the interval to make the effect more obvious.

let timeout = 500;
let $text = $('.text-sequence .text');
let updateActiveText = () => {
  let $current = $text.filter('.active').removeClass('active');
  let $next = $current.next();
  if ($next.length == 0)
    $next = $text.first();    
  $next.addClass('active');
}

updateActiveText(); // on load
setInterval(updateActiveText, timeout) // every n iterval;
.text {
  opacity: 0
}

.text.active {
  opacity: 1
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="text-sequence">
  <div class="text">Text 1</div>
  <div class="text">Text 2</div>
  <div class="text">Text 3</div>
  <div class="text">Text 4</div>
  <div class="text">Text 5</div>
  <div class="text">Text 6</div>
</div>

Consider the following setInterval() example.

$(function() {
  var timeout = 2000
  var index = 0;
  setInterval(function() {
    console.log(index);
    $(".active").removeClass("active");
    $(".text-sequence .text").eq(index++).addClass("active");
    if (index >= $(".text-sequence .text").length) {
      index = 0;
    }
  }, timeout);
});
.text {
  opacity: 0
}

.text.active {
  opacity: 1
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="text-sequence">
  <div class="text">Text 1</div>
  <div class="text">Text 2</div>
  <div class="text">Text 3</div>
  <div class="text">Text 4</div>
  <div class="text">Text 5</div>
  <div class="text">Text 6</div>
</div>

This will keep running over and over.

The setInterval() method, offered on the Window and Worker interfaces, repeatedly calls a function or executes a code snippet, with a fixed time delay between each call.

This also give you the option to clearInterval() if needed.

You could also do this in a few other ways.

$(function() {
  var timeout = 2000
  var index = 0;
  setInterval(function() {
    console.log(index);
    $(".active").removeClass("active").animate({
      opacity: 0
    }, 1000);
    $(".text-sequence .text").eq(index++).animate({
      opacity: 1
    }, 1000).addClass("active");
    if (index >= $(".text-sequence .text").length) {
      index = 0;
    }
  }, timeout);
});
.text {
  opacity: 0
}

.text.active {
  opacity: 1
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="text-sequence">
  <div class="text">Text 1</div>
  <div class="text">Text 2</div>
  <div class="text">Text 3</div>
  <div class="text">Text 4</div>
  <div class="text">Text 5</div>
  <div class="text">Text 6</div>
</div>

Related