Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fadeOut() callback completes before fading is done

I am working on a font-test page that should switch the font of the header and paragraph tags on click. Which works fine but the experience is really jarring so I want to smooth it out with the following path:

fadeout -> do the font swap -> fade in

But the code runs the font swap first, then the animation.

I have the following code snippet, I am only including the jQuery because it's the root cause of my problem.

// Anytime a card is clicked
$('.card').click(function(){
    // Call card by id and switch the fonts
    var id = "#" + this.parentElement.id;
    $(this).fadeOut(900,swapFont(id));
    $(this).fadeIn(500);
    // attach the above to some sort of transition callback

});

// Function to swap the font around so that the header is now the body font and the body font is now the header font
function swapFont(id) {
 // font-swap logic in here which works fine
}
like image 506
Callat Avatar asked Dec 24 '22 13:12

Callat


2 Answers

The issue is because the fadeOut() animation is (effectively) asynchronous. This means the next statement will be evaluated while the animation is in progress - hence the behaviour you're seeing. To fix this you need to use the callback pattern that the fadeX() methods provide.

Also, you're passing the result of the immediate execution of swapFont() to the callback, instead of a function reference to run when the event occurs. Try this:

$('.card').click(function(){
  var id = "#" + this.parentElement.id;
  $(this).fadeOut(900, function() {
    swapFont(id);
    $(this).fadeIn(500);
  });
});
like image 75
Rory McCrossan Avatar answered Jan 02 '23 03:01

Rory McCrossan


You are currently passing the result of the swapFont() call, instead you need to point to the function itself.

So this:

$(this).fadeOut(900,swapFont(id));

is the same as:

 var x = swapFont(id);
 $(this).fadeOut(900, x);

Easiest way is to wrap it in an anonymous function:

$(this).fadeOut(900, function() { swapFont(id) });

Edit:

The fadeIn will also execute before the fadeOut has completed. You can add a .delay or, better, call the fadeIn in the callback as per Rory's answer (so I won't repeat here).

like image 38
freedomn-m Avatar answered Jan 02 '23 04:01

freedomn-m