0

I am trying to loop through an array of CSS classes to change the linear gradient colors of the body element on a set interval in jQuery.

CSS

.class1 {
  background-image: linear-gradient(to right, crimson, gold);
}

.class2 {
  background-image: linear-gradient(to right, blue, #cd7f32);
}

.class3 {
  background-image: linear-gradient(to right, yellow, black);
}

.class4 {
  background-image: linear-gradient(to right, silver, green)
}

jQuery

$(document).ready(function(){
  var classList = ['.class1', '.class2', '.class3', '.class4'];
  setInterval(function(){
    for(var i=0; i<classList.length; i++){
      $(document.body).addClass(classList[i]);
      $(document.body).removeClass(classList[i-1]);
    }, 5000);
)};
raginghobo
  • 35
  • 4
  • How do you expect that `for` loop to work? – Herohtar Jul 23 '19 at 04:05
  • I see there were several things wrong with my code, including the . from the class names in the array. Why did wrapping everything in a function and not using a for loop work? – raginghobo Jul 23 '19 at 04:32
  • `setInterval` just repeatedly calls the given function after the specified interval, but does nothing to the code inside -- your `for` loop runs through almost instantly every time the function is called. – Herohtar Jul 23 '19 at 04:40

3 Answers3

1

Firstly, you need to remove the . from your class names.

Now, since your aim is to apply classes sequentially, you can keep a variable to keep track of the current index and use removeClass() to remove all classes applied before you add the new class in the next iteration.

var classList = ['class1', 'class2', 'class3', 'class4'];

DEMO

$(document).ready(function() {
  var classList = ['class1', 'class2', 'class3', 'class4'];
  var i = 0;
  setInterval(function() {
    $(document.body).removeClass();
    i = i + 1;
    $(document.body).addClass(classList[i]);
    if (i == 3) {
      i = 0;
    }
  }, 1000);
});
.class1 {
  background-image: linear-gradient(to right, crimson, gold);
}

.class2 {
  background-image: linear-gradient(to right, blue, #cd7f32);
}

.class3 {
  background-image: linear-gradient(to right, yellow, black);
}

.class4 {
  background-image: linear-gradient(to right, silver, green)
}
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
Nidhin Joseph
  • 9,981
  • 4
  • 26
  • 48
  • You did more than just remove `.` from the class names; those changes should be explained as well, especially the `setInterval` part, because that was one of the major things wrong in the OP's code. – Herohtar Jul 23 '19 at 04:32
  • Yep, I understand, Have edited my answer to include details. – Nidhin Joseph Jul 23 '19 at 04:35
0

Another way to solve it, although it does exactly the same as the approved answer. I've commented the important parts for you:

var classList = ['class1', 'class2', 'class3', 'class4'];
var interval, index = 0;

$(document).ready(function() {
  interval = setInterval(setClass, 5000); // Interval as variable so you can delete it later
  setClass(); // Call once, so it sets the class when the document is ready
});

function setClass() {
  $(document.body).attr("class",classList[index]); // Rewrites the class list of the body
  index == classList.length-1 ? index = 0 : index++; // If last index is reached, start at 0 again
}
.class1 {
  background-image: linear-gradient(to right, crimson, gold);
}

.class2 {
  background-image: linear-gradient(to right, blue, #cd7f32);
}

.class3 {
  background-image: linear-gradient(to right, yellow, black);
}

.class4 {
  background-image: linear-gradient(to right, silver, green)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Oh and this one is dynamic, so no matter how many classes you have in the classList, it will loop through them all.

NoNickAvailable
  • 398
  • 1
  • 2
  • 12
  • 1
    Although I already marked the 'answer,' I like your solution better because it is clearer to me what the code is doing. Thank you! – raginghobo Jul 29 '19 at 19:48
-2

In the following example, I'm trying to use your idea to make div show and hide using setInterval by matching its id(div ID)

The first div will appear after a pause of 3.5 seconds and will follow up with the divs which will change every second

$('html').addClass('js');

$(function() {

  var timer = setInterval(showDiv, 2000);

  var counter = 0;

  function showDiv() {
    if (counter == 0) {
      counter++;
      return;
    }

    $('div', '#container')
      .stop()
      .hide()
      .filter(function() {
        return this.id.match('class' + counter);
      })
      .show('fast');
    counter == 4 ? counter = 0 : counter++;

  }

});
body {
  background-color: #fff;
  font: 16px Helvetica, Arial;
  color: #000;
}

.display {
  width: 300px;
  height: 200px;
  border: 2px solid #000;
}

.js .display {
  display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
  <title>Sandbox</title>
  <meta http-equiv="Content-type" content="text/html; charset=utf-8" />

</head>

<body>
  <p>The first div will display after 3 seconds...</p>
  <div id='container'>
    <div id='class1' class='display' style="background-image: linear-gradient(to right, crimson, gold);">
      class1
    </div>
    <div id='class2' class='display' style=" background-image: linear-gradient(to right, blue, #cd7f32);">
      class2
    </div>
    <div id='class3' class='display' style="background-image: linear-gradient(to right, yellow, black);">
      class3
    </div>
    <div id='class4' class='display' style="background-image: linear-gradient(to right, silver, green);">
      class4
    </div>
    <div>
</body>

</html>

You're good to go... Hope this helps!!

Akshay Mulgavkar
  • 1,727
  • 9
  • 22