0

so I'm trying to create a really simple animation using jQuery but the callback for fadeOut doesn't ever happen.

Here is the code below:

var move = function(target, speed) {
    $(target).delay(200).animate({bottom: "-=20"},
        speed,
        function() {
            $(this).fadeOut(200, function() {
                $(this).css("bottom", "+=20");
            });
            $(this).fadeIn(200);
        }
    );
    move(target, speed);
};

move(".fa-arrow-down", 500);

I've tried several different things like checking it out in the console, setting various breakpoints (mainly right at $(this).css("bottom", "+=20");, right above this line, and right below this line).

I'm not really sure why it's not happening. Any help is appreciated and if you could please also explain what the issue actually is so I can learn too. Here's a fiddle.

djthoms
  • 3,026
  • 2
  • 31
  • 56
  • 3
    Open your developer tools to see your error. "Too much recursion." You're invoking the recursive `move()` immediately instead of in the callback. – cookie monster May 30 '14 at 18:29
  • Says the max call stack size is exceeded so yes. But I have no idea how to rectify this. – djthoms May 30 '14 at 18:30
  • As I just said, you're invoking `move()` immediately instead of waiting for the callback. This means it invokes `move()` at a rate of frequency equal to the time it takes to invoke `.delay().animate()`, but without waiting for them to finish. In other words, `move()` will be invoked tens of thousands of times even before the first `.delay()` is finished. – cookie monster May 30 '14 at 18:32
  • 1
    Ahhhh, I see what you're saying! – djthoms May 30 '14 at 18:34
  • I'm curious. Can it still hit the max amount of recursion? Suppose with my fix someone sat on the page long enough, would it hit the limit on recursion eventually? There's not really a base case like in C to end it and return.... – Jonathan May 30 '14 at 18:45
  • I'm going to test it out >:} – Jonathan May 30 '14 at 18:47
  • 1
    Interesting, I found [**this**](http://stackoverflow.com/questions/2805172/what-are-the-js-recursion-limits-for-firefox-chrome-safari-ie-etc). Apparently it will come to an end eventually if you don't refresh the page. – Jonathan May 30 '14 at 18:51

1 Answers1

4

You need to move the call to move(target, speed) to inside the complete function of the fadeIn.

DEMO

var move = function (target, speed) {
    $(target).delay(200).animate({
        bottom: "-=20"
    },
    speed,

    function () {
        $(this).fadeOut(200, function () {
            $(this).css("bottom", "+=20");
        });
        $(this).fadeIn(200, function () {
            move(target, speed);


        });
    });
};

move(".fa-arrow-down", 500);

But I can't take all the credit... cookie monster was first to see the recursion error. Just like he said, this works because it adds a delay to each time you call move()

As I just said, you're invoking move() immediately instead of waiting for the callback. This means it invokes move() at a rate of frequency equal to the time it takes to invoke .delay().animate(), but without waiting for them to finish. In other words, move() will be invoked tens of thousands of times even before the first .delay() is finished -- cookie monster

Community
  • 1
  • 1
Jonathan
  • 1,126
  • 10
  • 19