3

I did some searching and I'm not even sure if what I want to do is good javascript practice. I have a while loop that I would like to exit from early if a stop button is clicked.

$( "#go" ).click(function() {
  var gotime = 1;
  while (gotime < 100) {
    for(i = 0; i < 2; i++){
      var divName = "floatName" + i;
      console.log(divName);
      $( "#" + divName ).animate({
        left: Math.random()*500 + "px",
        top: Math.random()*500 + "px"
      }, 500, function() {
        // Animation complete.
      });
    };

    gotime += 1;

    $( "stop" ).click(function() {
      gotime = 101;
    });
    };
});

This doesn't work though. I originally had an endless loop (not incrementing gotime).

http://jsfiddle.net/cvoxe465/

3 Answers 3

3

Actually it stops if you wait for some time. The problem is you execute animation very often and $.animate have to queue it. There is $.stop method that allow you to stop the currently-running animation. DEMO

$( "#stop" ).click(function() {
  gotime = 101;
  $('#floatName0, #floatName1').stop(true, true);
});

EDIT:

Note that in the code that you provided there is mistake. Instead $("stop") you need to use $("#stop").

Sign up to request clarification or add additional context in comments.

1 Comment

Please also mention that $(stop) should have been $(#stop), that was the reason why the click button event was not firing and eventually we had to wait for the loop to finish.
1

You may use setInterval:

Js:

var interval;
$("#go").click(function () {
    var gotime = 1;
    interval = setInterval(function () {
        for (i = 0; i < 2; i++) {
            var divName = "floatName" + i;
            console.log(divName);
            $("#" + divName).css({
                left: Math.random() * 500 + "px",
                top: Math.random() * 500 + "px"
            });
        };
        gotime += 1;
        if (gotime > 100) {
            clearInterval(interval);
        }
    }, 500)
});
$("#stop").on('click', function () {
    clearInterval(interval);
});

css:

#randomFloat {
    color: red;
}
#floatName1, #floatName0 {
    transition : 0.5s left, 0.5s top;
}

Fiddle

4 Comments

Thanks, that makes sense. I guess it loops through the for very fast. I was thinking it looped through every 500ms, which was the animation time.
@DougSmith : HI, The reason why i posted this answer here is because you asked for good javascript practice. If you make variable gotime = 101, when user clicks on stop then you can never resume animation. If you remove it then even if you stop the animation the while loop will run 100 times. Now read the answers again and see which is better one. :)
@AJ: yes, and I can also put the transition into #randomFloat because I see that it gets inherited. Thanks!
@AJ I'm coming back to this and doing some debugging. This strategy works well but there is a problem is the user clicks #go and then clicks #go again. The animation will not stop after doing this. I forked the Fiddle to try and use the gotime to toggle the clearInterval but that didn't seem to work.
1

animate doesn't block the loop. The animations are stacked up and then executed, but the loop finishes a lot earlier. Here is something that works:

var loopAllowed = false;
$('#go').click(function(){
    loopAllowed = true;
    var max = 2;
    var loop = function(){
        for(var i = 0; i < max; i++){
            var divName = "floatName" + i;
            $( "#" + divName ).animate({
                left: Math.random()*500 + "px",
                top: Math.random()*500 + "px"
            }, 500, i === max - 1 && loopAllowed ? loop : undefined);
        }
    };
    loop();
});

$('#stop').click(function(){
    loopAllowed = false;    
});

JSFiddle. We manually call the loop function after the animation has ended (by passing it as the callback function). If loopAllowed is false (e.g. set to false by clicking #stop), then it won't be passed as the callback function and the looping stops.

3 Comments

I like this solution because I plan on animating several more names, and this solution doesn't require more calls to floatNameX
Could you briefly explain what the i == max - 1 && loopAllowed ? loop : undefined does? I understand that the i == max - 1 && loopAllowed checks for a condition, but I don't get the ? loop : undefined. As well, I don't see how these parts fit in with the documentation for jquery's docs api.jquery.com/animate. Is it part of the queue option?
@DougSmith It's the ternary operator. It's essentially a shorthand for if - if the condition is true, pass loop as callback, if it is false, pass undefined as callback (which will end the loop). The callback is called after the animation is finished - which is why we can loop like this (after the animation, loop is called again). The queue option is true by default (the animations are placed in a queue by default and then executed sequentially), but my code doesn't touch that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.