views:

233

answers:

3

Hi,

I'm trying to do the following:

I have two sets of DOM elements on a page. All elements in the first set carry the class display-element, and the second set of elements carry the class edit-element.

Now I have a button (id=edit-button). When I click this button, I want all the display-elements to fade out, and all the edit-elements to appear.

I naturally did:

$('#edit-button').click(function(){
    $('.display-element').fadeOut(300, function() {
        $('.edit-element').fadeIn(300);
    });
});

I found to my surprise that this did not work as expected. This is what happened: as soon as the first element with class display-element faded out, all the edit-elements started fading in.

Now is there any easy way (perhaps something in the documentation I missed) using which I can have all the edit-elements start fading in only after all display-elements have faded out?

Thanks
jrh

A: 

Why would this happen, really? I mean, it appears, that you are starting the animations at the same time (there is only one call to .fadeOut after all, right?). I guess, this is because $() yields an array and when you call .fadeOut, jQuery iterates through the array and performs whatever it performs for each of its elements. Starting from the first. Since the callback gets "attached" to every animation, you see the visible effect of the first callback.

I guess, you could sidestep this by iterating through the array of the returned elements yourself and making sure, that you attach the callback only to the last one.

$('#edit-button').click(function(){
    var display_elements = $('.display-element');
    var len = display_elements.length;
    for (var i = 0; i < len-1; i++) {
        $(display_elements[i]).fadeOut(300); // no callback
    }
    $(display_elements[len-1]).fadeOut(300, function() {
        $('.edit-element').fadeIn(300);
    }); // last element - attach callback
});

I am sorry if the code is off, I must admit, that my javascript-fu is not very strong :)

shylent
A: 

The solution is to use a setTimeout on the fading in function

$('#edit-button').click(function(){
    $('.display-element').fadeOut(300);
setTimeout("$('.edit-element').fadeIn(300);", 300);
});

That javascript function will delay the trigger of the the fading in function for 300 miliseconds

kio
this will work approximately, but ... time durations are not so reliable, especially in milliseconds..
Here Be Wolves
+1  A: 

Well, having not found any 'nifty API method', I resolved to this:

$('#edit-button').click(function() {
    var displays = $('.display-element');
    var counter = 0;
    var max = displays.length;
    displays.fadeOut(300, function() {
        counter++;
        if( counter>=max ) $('.input-element').fadeIn(300);
    }
});

This is essentially @shylent's answer, with more 'javascript-fu' :)

Here Be Wolves
Ah yes, this is certainly better :)
shylent