2

I'm stuck looking for the right way to stop a setTimeout call recursive function. I want to be able to restart an animation without having to wait for the animation to finish.

Any help would be awesome!!

var viewArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

var started = 0;

function animator() {
  if (!started) {
    console.log("Start... ");
    started = 1;
    var i = 0;
    count = 1;

    (function iterator() { // <-- how can I kill this iterator function when the user clicks stop
      document.getElementById("output").innerHTML = viewArray[i];
      if (++i < viewArray.length) {
        setTimeout(iterator, 1000);
        count++
        if (count >= viewArray.length) {
          started = 0;
        } //when animation complete (number reaches 10) allow start animation button to work again 
      }
    })();

  } else {
    console.log("Wait..."); // inactivate button
  }

  started = 1;
}
<div id="output" style="margin: 40px; font-size:130px"></div>
<div style="margin: 40px;">
  <button id="on" onclick="animator();">Start Animation</button>
</div>
<div style="margin: 40px;">
  <button id="off">Stop Animation</button>
</div>
8
  • 3
    Check out clearTimeout Commented Feb 24, 2016 at 23:30
  • 2
    Calling setTimeout to set a new timeout for the same function isn't technically a recursive function. Commented Feb 24, 2016 at 23:32
  • I have but don't think I'm implementing it correctly. I'm missing something :( Commented Feb 24, 2016 at 23:32
  • There is no call to clearTimeout in your code, so yeah, you're missing something. :) Have you stored the timer id returned by setTimeout, so you can pass it to clearTimeout? Commented Feb 24, 2016 at 23:33
  • 2
    @GolezTrol - The technical term for when a function uses setTimeout to call itself is "recurse-ish". Commented Feb 24, 2016 at 23:38

2 Answers 2

3

You can easily solve this with state. Simply add a variable to your code called

  var isRunning = false;

which it to true when you start the animation, and false to stop the animation. Then inside your iterator function, check to see if isRunning is false. If isRunning === false, you don't call the next setTimeout, hence stopping the animation.

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

Comments

2

I'd probably use setInterval/clearInterval outside your interval function. You definitely want recurring intervals instead of single timeouts when you think about it.

So basically:

var something;

function start() {
  something = setInterval(interval, 1000);
}

function interval() {
  //animation code
}

function stop() {
  clearInterval(something);
}

Comments

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.