3

I am fading elements one by one but it seems it all fades at once.

How can I fade elements one by one. Only if one fades completely, should the second start fading.

I loop and fade it like this

$(ele).fadeIn('slow');
Hitz
  • 1,041
  • 4
  • 12
  • 27

3 Answers3

4

fadeIn has a callback that executes when fading is completed. Add to every element the class elemX, where x is the order of fading. Then use the following code:

startFading(1);

function startFading(order) {
   $(".ele" + order).fadeIn('slow', function() {
        if (order < orderMax) {
            startFading(order+1);
        }
   });
}
kgiannakakis
  • 103,016
  • 27
  • 158
  • 194
  • Recursion in JavaScript! Very nice. – montrealist May 06 '09 at 13:28
  • thanks can this be replaced for elements with same class. I see that you are using a order. However can this be done using class – Hitz May 06 '09 at 14:05
  • If you want to apply this on elements with class 'fade', then you add the classes 'fadeorder1', 'fadeorder2', ... to them. An element can have more than one class, so this class='fade fadeorder1', is perfectly OK. – kgiannakakis May 06 '09 at 14:20
3

I made this quick/easy jQuery plugin for you to do just what you want. :-)

$.fn.extend({
    serial_fade: function(o) {
        if(!o.speed || o.speed == undefined || o.speed == null) { o.speed = 'slow'; }
        if(!o.fade || o.fade == undefined || o.fade == null)    { o.fade = 'in'; }
        if(!o.index || o.index == undefined || o.index == null) { o.index = 0; }
        var s = this.selector;
        if(o.fade.toLowerCase() == 'in') {
            return this.eq(o.index).fadeIn(o.speed, function() {
                o.index++;
                if($(s).eq(o.index).length > 0) {
                    $(s).serial_fade({speed:o.speed,fade:o.fade,index:o.index});
                }
            });
        } else {
            return this.eq(o.index).fadeOut(o.speed, function() {
                o.index++;
                if($(s).eq(o.index).length > 0) {
                    $(s).serial_fade({speed:o.speed,fade:o.fade,index:o.index});
                }
            });
        }
    }
});

// To call it just do this:
$(ele).serial_fade({speed:'slow',fade:'in'});

// Optionally, you can pass which element you want to start with (0-based):
 $('a').serial_fade({speed:'slow',fade:'in',index:2});

// If you want to start with element 2 (3, really) and fade all the rest *out*
// sequentially, verrry slowly:
$(ele).serial_fade({speed:5000,fade:'out',index:2});

It should work with ANY kind of selector just like any other jQuery method does. I hope this works out for you.

Edit: I extended it so that it can do fade ins and fade outs now. It just seems more useful that way...

KyleFarris
  • 17,274
  • 5
  • 40
  • 40
  • You're welcome. I added some new functionality to it... just so you know. – KyleFarris May 06 '09 at 15:44
  • Why is my answer being voted down?? Its a perfectly legitimate, flexible, working answer to this persons problem. Doesn't make any sense. Is someone sour about it or something? I'd at least like to know why it's being voted down. :-( – KyleFarris May 07 '09 at 04:19
0

You could make this generic and not force it to be for fading only.

function depth(collection, fun, i) {
    if (i === undefined)
        depth(collection, fun, 0);
    else
        if (i < collection.length)
            fun(collection[i], function(){
                depth(collection, fun, i + 1);
            });
};

depth($("a"), function(elem, fun) {
    $(elem).fadeIn('slow', fun);
});
gradbot
  • 13,732
  • 5
  • 36
  • 69