admin管理员组

文章数量:1410697

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 plete (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>

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 plete (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>
Share Improve this question edited Feb 24, 2016 at 23:32 Mike Cluck 32.5k13 gold badges83 silver badges94 bronze badges asked Feb 24, 2016 at 23:27 BridgbroBridgbro 2691 gold badge3 silver badges17 bronze badges 8
  • 3 Check out clearTimeout – Mike Cluck 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. – GolezTrol Commented Feb 24, 2016 at 23:32
  • I have but don't think I'm implementing it correctly. I'm missing something :( – Bridgbro 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? – GolezTrol Commented Feb 24, 2016 at 23:33
  • 2 @GolezTrol - The technical term for when a function uses setTimeout to call itself is "recurse-ish". – nnnnnn Commented Feb 24, 2016 at 23:38
 |  Show 3 more ments

2 Answers 2

Reset to default 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.

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);
}

本文标签: jqueryHow to Stop a Recursive Function in JavaScriptStack Overflow