13

I have this simple function in jQuery:

function detailspage(page) {

  if (page != checkcurrent) {

    checkcurrent = page;

    $('div#details').children("div").slideUp("slow", function() {

        $('div#details').children("div"+page).slideDown("slow");

    });

  };

};

I have put three <div>'s inside another <div> called <div id="details">, and they are all slided up and out of sight by default. I now wish to make each of them slide down, when a button for each of them is clicked. Of course a <div> that is open must first be slided up and out of sight, before the new one is slided down. That is why I have tried this simple callback function above.

(The page variable contains an id for one of the div's, like #info or #cast_crew.)

But it doesn't work: You can see the error by clicking the three buttons on the left in the bottom of the page, named "Cast & crew", "Info" and "Galleri".

It all works apart from the callback function that doesn't seem to cause any delay. The callback has no effect. I simply want the slidedown of the new box to start when the slideup of the current box is finished.

What is wrong? Why doesn't my callback work?

Thank you.

Steeven
  • 4,057
  • 8
  • 38
  • 68

2 Answers2

50

I would take a look at the promise function in jquery to ensure all elements have completed the animation: http://api.jquery.com/promise/

For your example:

function detailspage(page) {
    if (page != checkcurrent) {
        // so we only have to search the dom once
        var details = $('div#details');
        checkcurrent = page;
        details.children("div").slideUp("slow").promise().done(
            function() {
                $('div' + page).slideDown("slow");
            });
    };
};

Working example: http://jsfiddle.net/cm3pv/6/

Gary.S
  • 7,076
  • 1
  • 26
  • 36
  • 1
    MAGIC! I was having the same issue as the OP. The callback just wasn't working like it's supposed to. It was firing immediately instead up waiting for `slideUp()` to finish. Tried implementing `.promise().done()` exactly like you're example and BOOM! Problem solved! Thanks :) – norsewulf Dec 12 '13 at 08:31
  • 1
    GREAT!! i know this is old but man i was looking for a long while trying to figure it out. I had this long post i was about to make when it came to me. "im probably not the one with this problem. Tried the .promise/.done and BAM! it worked PERFECTLY. Thanks – somdow May 02 '15 at 13:47
  • 2
    Any explanation to why passing the complete function as the second parameter, as suggested by the documentation, doesn't work? – Sal Jun 07 '15 at 18:22
  • Cy complete on fadeIn was firing few times. (console.log was fired up to 6 times). Promise() resolved my issues – Grzegorz Jan 27 '16 at 16:11
3

I tried Gary.S's accepted answer, but my function was still firing before the animation was complete. I found a suggestion on another post How to get jQuery to wait until an effect is finished?

Needed to use $.when( func ).done( function () { myFunc(); } );

I HAD to put my function in a new function.

What I ended up using looked like this (to use your example):

$.when( $('div#details').children("div").slideUp("slow") ).done(){ function() {
    $('div#details').children("div"+page).slideDown("slow");
});