1

Possible Duplicate:
jquery add a fade to an .addClass

Here is my jsFiddle example: http://jsfiddle.net/sLzGc/

I am trying to create an effect where it appears options 1 through 3 are being rotated. Every 1.2 seconds the green class is removed from the option that has it and the green class is added to the next option. The idea is that the rotation through the three options happens five times (i<5) before the final function alert('Finished') is executed.

I'm trying to use setTimeout(), but I'm open to using .delay(), another jQuery function, or some other option.

Here is my JavaScript/jQuery:

alert('Start');

sampleFunction();

function sampleFunction() {

for (i=0; i<5; i++) {

  setTimeout(function() {
    $('#option2').addClass('green');
    $('#option1').removeClass('green');
  },1200);

  setTimeout(function() {
    $('#option3').addClass('green');
    $('#option2').removeClass('green');
  },1200);

  setTimeout(function() {
    $('#option1').addClass('green');    
    $('#option2').removeClass('green');
  },1200);

}//end for loop

}

alert('Finished');​

My whole example is on jsFiddle: http://jsfiddle.net/sLzGc/

Thanks for any help or insight you can offer!

Community
  • 1
  • 1
Mark Rummel
  • 2,920
  • 10
  • 37
  • 52

4 Answers4

2

Here's how I would approach the problem:

​(​function() {
    var options = [$("#option1"), $("#option2"), $("#option3")],
        cycles = 5,
        i = 0,
        $last = $(null);

    (function next() { 
        if(i < cycles * options.length) {
            $last.removeClass("green");
            $last = options[i % options.length].addClass("green");
            i++;
            setTimeout(next, 1200);
        } else {
            $last.removeClass("green");
            alert("finished!"); //do any other "we're done" stuff here.
        }
    }());
}());​

It's pretty straightforward and the cool part is that you can add elements to the list of elements to cycle through pretty easily (just add them to options). You can also set the number of cycles if you want. I didn't make the class or delay length a variable, but that would be very simple in case you wanted to do that.

You can see a demo here:

http://jsfiddle.net/D7SR8/

You might also consider having a callback function at the end and putting the alert() in there. That would be more reusable.

Pete
  • 2,538
  • 13
  • 15
  • +1 Very clean, simple, and easily customizeable. – Josh Mein Sep 08 '12 at 01:32
  • As a possible improvement, you could also just get all of the elements with a specific class. That way you wouldn't not have to list each of the selectors indiviudally. http://jsfiddle.net/D7SR8/2/ – Josh Mein Sep 08 '12 at 01:55
  • Agreed, @JoshMein, except that you wouldn't be able to control the order in which it selected each item. It's probably easier to control like this. The cool thing is, though, since it uses jQuery objects, you could highlight a bunch at a time if you wanted. It's actually a handy bit of code when it comes down to it. :-) – Pete Sep 09 '12 at 01:10
  • @Pete Very cool solution! I added a variable `count = options.length`. Thanks! – Mark Rummel Sep 15 '12 at 03:52
1

If you are wanting to use setTimeouts then your code could look something like this:

var iteration = 0;
alert('start');
rotateColors();

function rotateColors() {
    setTimeout(function() {
        $('#option2').addClass('green');
        $('#option1').removeClass('green');
            setTimeout(function() {
                $('#option3').addClass('green');
                $('#option2').removeClass('green');
                setTimeout(function() {
                    $('#option1').addClass('green');    
                    $('#option3').removeClass('green');
                    iteration += 1;

                    if(iteration < 5)
                        rotateColors();
                    else
                        alert('finished');
            },1200);
        },1200);
    },1200);   
}

Live DEMO

Josh Mein
  • 28,107
  • 15
  • 76
  • 87
  • 1
    @Mark Rummel I will try to think of a cleaner jquery version too if I can. – Josh Mein Sep 08 '12 at 01:20
  • Thanks! I've got your solution working! And thanks for the jsFiddle demo! A cleaner jQuery solution would be nice. I'm also reviewing Pete's solution since it sounds like it would allow for more flexibility down the road, but your answer certainly solved what I was needing! Thanks again! – Mark Rummel Sep 08 '12 at 03:13
  • @MarkRummel I stopped working on a cleaner solution because what Pete offers was similar to what I was thinking. Make sure to check out my slight tweek to his code though, it will make it even easier for you. I attached a jsfiddle in the comments of his answer. – Josh Mein Sep 08 '12 at 03:13
0
alert('Start');
 var varobj=0;
sampleFunction();

function sampleFunction() {
setTimeout(function() {
    $('#option2').addClass('green');
    $('#option1').removeClass('green');

  },1200, setTimeout(function() {
        $('#option3').addClass('green');
        $('#option2').removeClass('green');

      },1200,setTimeout(function() {
            $('#option1').addClass('green');    
            $('#option3').removeClass('green'); if(varobj<5){varobj=varobj+1;sampleFunction();}else{ alert('finished');}
      },1200);););}

this is a approch how call function after execution of other in settimeout

0

I use both setTimeout() and setInterval() to do this and then clear the interval after 5 executions. If you want them to all end on a certain color or any other modifications let me know! I just modified it to loop through how you asked. http://jsfiddle.net/sLzGc/9/

sampleFunction();

function sampleFunction() {
    alert('Start');
    $('#option1').addClass('disabled');

    var i = 0;
    var shift = function() {
        setTimeout(function() {
            $('#option1').toggleClass('disabled');
            $('#option2').toggleClass('disabled');
        }, 0);
        setTimeout(function() {
            $('#option2').toggleClass('disabled');
            $('#option3').toggleClass('disabled');
        }, 400);
        setTimeout(function() {
            $('#option3').toggleClass('disabled');
            $('#option1').toggleClass('disabled');
        }, 800);
    };
    var interval = setInterval(function() {
        ++i;
        if (i == 5) {
            clearTimeout(interval);
            alert('Finished');
        } else {
            shift();
        }
    }, 1200);

    shift();
}​
Evan Kennedy
  • 3,975
  • 1
  • 25
  • 31