Boris Kozarac
Boris Kozarac

Reputation: 635

Change class every few seconds from values in array

I am trying to change class on a div every 3 seconds. Classes are in array, previous class should be removed and next one added. "First" should be first, then "second", then "third" and back to loop.

I know how to addClass('something') but I am stuck on part where code should put the next available class from array.

<div id="main"></div>

    jQuery(document).ready(function ($) {
    var images = ['first', 'second', 'third'];

    function changeBackground() {
        var className = $('#main').attr('class');
        if (className == null)
            className = images[0];

        $('#main').removeClass(function () {
            var newClass = // find value in array and take next value, if end of array get first
                $(this).addClass(newClass);
        });
    }

    changeBackground();
    setInterval(changeBackground, 2000);
});

https://jsfiddle.net/skd636fc/3/

Upvotes: 4

Views: 2462

Answers (5)

T.J. Crowder
T.J. Crowder

Reputation: 1074268

You don't need to pass a function into removeClass. You do need to keep track of what class you're on so you can move to the next on the next timer tick. I've explained in the comments:

jQuery(document).ready(function($){   

    var images = ['first', 'second', 'third'];
    // Remember where we are in the array, start just before the first entry
    var classIndex = -1;

    function changeBackground() {

        // Grab the element
        var main = $("#main");

        // If this isn't the first time, remove the previous class
        if (classIndex >= 0) {
            main.removeClass(images[classIndex]);
        }

        // Update the index, wrapping around when we reach the end of the array
        classIndex = (classIndex + 1) % images.length;

        // Add the new class
        main.addClass(images[classIndex]);
    }

    changeBackground();
    setInterval(changeBackground, 2000);

});

Notes about the above:

  • It's obviously much more compact without explanatory comments
  • It won't wipe out other, unrelated classes on #main (whereas solutions using removeClass() with no arguments will)

Here's a more compact version if you're into that kind of thing. I wouldn't suggest compacting it to quite this degree, though. :-)

jQuery(document).ready(function($){   
    var classIndex = 0, images = ['first', 'second', 'third'];
    $("#main").addClass(images[classIndex]);
    setInterval(function () {
        $("#main")
            .removeClass(images[classIndex])
            .addClass(images[classIndex = (classIndex + 1) % images.length]);
    }, 2000);
});

Upvotes: 3

Tushar
Tushar

Reputation: 87203

You can use a counter to keep the track of the class index.

Demo

jQuery(document).ready(function ($) {
    var images = ['first', 'second', 'third'],
        i = 0; // Counter to keep track of the class index

    // Cache the element reference
    var $main = $('#main');

    function changeBackground() {
        $main.attr('class', images[i++]); // Set the class attribute value
        i = i % images.length; // If greater than class length, reset back to 0
    }

    // Add first class on page load
    changeBackground();
    setInterval(changeBackground, 2000);
});

jQuery(document).ready(function ($) {
    var images = ['first', 'second', 'third'],
        i = 0;

    var $main = $('#main');
    function changeBackground() {
        $main.attr('class', images[i++]);
        i = i % images.length;
    }

    changeBackground();
    setInterval(changeBackground, 2000);
});
#main {
    width: 200px;
    height: 200px;
    border: 1px solid red;
}

.first {
    background-color: #f01 !important;
}

.second {
    background-color: blue;
}

.third {
    background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="main"></div>


If possible, add the first class to element from HTML

Demo

HTML:

<div id="main" class="first"></div>

JavaScript:

jQuery(document).ready(function ($) {
    var images = ['first', 'second', 'third'],
        i = 0;

    var $main = $('#main');
    setInterval(function () {
        $main.attr('class', images[++i % images.length]);
    }, 2000);
});

jQuery(document).ready(function ($) {
    var images = ['first', 'second', 'third'],
        i = 0;
    var $main = $('#main');
    setInterval(function () {
        $main.attr('class', images[++i % images.length]);
    }, 2000);
});
#main {
    width: 200px;
    height: 200px;
    border: 1px solid red;
}

.first {
    background-color: #f01 !important;
}

.second {
    background-color: blue;
}

.third {
    background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="main" class="first"></div>

Upvotes: 4

Waruna Manjula
Waruna Manjula

Reputation: 3477

 jQuery(document).ready(function($) {
     var images = ['first', 'second', 'third'],
     	i = 0;

     function changeBackground() {
         $('#main').attr('class', images[i++]);
         i = i % images.length;
     }

     changeBackground();
     setInterval(changeBackground, 2000);
 });
#main {
    width: 200px;
    height: 200px;
    border: 1px solid red;
}

.first {
    background-color: #f01 !important;
}

.second {
    background-color: blue;
}

.third {
    background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>

<div id="main"></div>

Upvotes: 3

Rajaprabhu Aravindasamy
Rajaprabhu Aravindasamy

Reputation: 67207

Try to use a counter variable. Increment it inside the setInterval and use modulo math to create a circular reference to the array's index,

var images = ['first', 'second', 'third'];
var $elem = $('#main'), cnt = 0;

function changeBackground(){
 $elem.removeClass().addClass(images[cnt++ % images.length]);
}

setInterval((changeBackground(), changeBackground), 2000);

DEMO

Upvotes: 2

Anoop Joshi P
Anoop Joshi P

Reputation: 25527

You can do,

var images = ['first', 'second', 'third'];

function changeBackground() {
  var className = $('#main').attr('class');
  var newIndex = (images.indexOf(className) + 1) % images.length;
  $("#main").removeClass().addClass(images[newIndex]);
}
setInterval(changeBackground, 2000);

Fiddle

Upvotes: 2

Related Questions