0

I've trying to run jQuery inside a for loop like this:

var frameNumber = 15; // How many frames are in your animation

for(var i = 1; i < frameNumber + 1; i++){
    var flipDelay = i * 100;

    $('.flipbook').delay(flipDelay).addClass('flipbook-' + i);
}

I'm trying to get the equivalent of this but with more flexibility so I can change how many frames I use:

$(function(){
    setTimeout(function(){ $(".flipbook").addClass("flipbook-1") }, 100 );
    setTimeout(function(){ $(".flipbook").addClass("flipbook-2") }, 200 );
    setTimeout(function(){ $(".flipbook").addClass("flipbook-3") }, 300 );
    setTimeout(function(){ $(".flipbook").addClass("flipbook-4") }, 400 );
    setTimeout(function(){ $(".flipbook").addClass("flipbook-5") }, 500 );
    setTimeout(function(){ $(".flipbook").addClass("flipbook-6") }, 600 );
    setTimeout(function(){ $(".flipbook").addClass("flipbook-7") }, 700 );
    setTimeout(function(){ $(".flipbook").addClass("flipbook-8") }, 800 );
    setTimeout(function(){ $(".flipbook").addClass("flipbook-9") }, 900 );
    setTimeout(function(){ $(".flipbook").addClass("flipbook-10") }, 1000 );
    setTimeout(function(){ $(".flipbook").addClass("flipbook-11") }, 1100 );
    setTimeout(function(){ $(".flipbook").addClass("flipbook-12") }, 1200 );
    setTimeout(function(){ $(".flipbook").addClass("flipbook-13") }, 1300 );
    setTimeout(function(){ $(".flipbook").addClass("flipbook-14") }, 1400 );
    setTimeout(function(){ $(".flipbook").addClass("flipbook-15") }, 1500 );
});

The classes are defined in a CSS stylesheet and each class has a different background applied to it. I just need jQuery/JS to loop through them until the last frame is reached.

EDIT: It's not the flipbook-01 vs flipbook-1 that's preventing me from getting this to work. Sorry about that confusion.

EDIT: I need my div to look like this after the function has ran:

<div class="flipbook flipbook-1 flipbook-2 flipbook-3 flipbook-4 ... flipbook-15"></div>

4 Answers4

1

Try this:

addClass('flipbook-' + (i<10?("0"+i):i));

This will add the missing zero for i<10. And about the delay - it would not work with addClass. You should stick with the setTimeout option.

vivek_nk
  • 1,590
  • 16
  • 27
  • updated. But, he already tried setTimeout, which is the answer, since delay is not going to work with addClass method. – vivek_nk Apr 16 '14 at 04:28
  • 1
    There's no reason he can't use `setTimeout()` in the loop and solve his requirement of easier to maintain code. Also, the OP has edited their question to say that the leading zero is NOT required so your answer isn't what the OP is now looking for. – jfriend00 Apr 16 '14 at 04:34
1

You are misusing the delay() function. jQuery will only queue up effects out-of-the-box (e.g. fadeIn() or slideUp()), and not things like show(), hide(), or addClass().

Example of non-working delay() with addClass(): http://jsbin.com/hayay/4/

Instead, you should just use setTimeout like others have mentioned. I'd recommend a recursive approach, though, instead of a for loop:

var frameNumber = 15;
showFrame(1);
function showFrame(i) {
  $('.flipbook').addClass('flipbook-' + i);
  if (i < frameNumber) {
    setTimeout(function() { showFrame(i+1); }, 100);
  }
}
Sean Adkinson
  • 8,425
  • 3
  • 45
  • 64
0

Fiddle Demo

var frameNumber = 15;
for (var i = 1; i < frameNumber + 1; i++) {
    (function (x) {
        setTimeout(function () {
            $('.flipbook').addClass('flipbook-' + x);
            console.log(x);
        }, x * 100)
    })(i)
}
Tushar Gupta - curioustushar
  • 58,085
  • 24
  • 103
  • 107
  • 1
    `('flipbook-'+ i)` will be `flipbook1` and not `flipbook01` as OP wants – asprin Apr 16 '14 at 04:09
  • Are you sure this works for you? I can't seem to see the flipbook-j class being applied to .flipbook. I see how it's supposed to work, but I can't get it to work for some reason. It's just an empty page. EDIT: Got it. But this is not what I'm looking for. I'll update my original post. –  Apr 16 '14 at 04:16
  • @dustindowell22 Check the updated answer and working demo see console log . – Tushar Gupta - curioustushar Apr 16 '14 at 04:39
0

As has been said already, the addClass() method is an immediate method invocation. It does not, by default, go through the animation queue which is required in order to work with .delay().

Here's an interesting solution I came up with that allows you to make any jQuery method work via the animation queue and thus you can sequence methods via the built-in animation queue, can use .delay() to control timing, can intersperse with other animations, etc...

// generic method to allow you to run any jQuery method through the animation queue
// so they will be serialized with other asynchronous animation methods
// such as .delay(), .animate(), .slideUp(), etc...
jQuery.fn.queueMethod = function(methodName /* arg1, arg2, ... */) {
    var self = this;
    var args = Array.prototype.slice.call(arguments, 1);
    self.queue(function(next) {
        self[methodName].apply(self, args);
        next();
    })
    return this;
}    

var frameNumber = 15; // How many frames are in your animation

for (var i = 1; i <= frameNumber; i++) {
    $('.flipbook').delay(100).queueMethod("addClass", "flipbook-" + i);
}

This will run each addClass method, 100ms apart.

Several working examples of slightly different ways of doing it: http://jsfiddle.net/jfriend00/38BbM/

jfriend00
  • 683,504
  • 96
  • 985
  • 979