Web_Designer
Web_Designer

Reputation: 74640

How to start and stop/pause setInterval?

I'm trying to pause and then play a setInterval loop.

After I have stopped the loop, the "start" button in my attempt doesn't seem to work :

input = document.getElementById("input");

function start() {
  add = setInterval("input.value++", 1000);
}
start();
<input type="number" id="input" />
<input type="button" onclick="clearInterval(add)" value="stop" />
<input type="button" onclick="start()" value="start" />

Is there a working way to do this?

Upvotes: 31

Views: 144288

Answers (8)

ESP
ESP

Reputation: 11

<!DOCTYPE html>
<html>

<body>

  <input type="button" onclick="mySetIntervalOff()" value="stop" />
  <input type="button" onclick="startInicio()" value="start" />

  <p id="demo"></p>

  <script>
    var mySetInterval;

    function startInicio() {
      mySetInterval = setInterval(function() {
        const date = new Date();
        document.getElementById("demo").innerHTML = date.toLocaleTimeString();
      }, 1000);
    }
    startInicio();
    clearInterval(mySetInterval);

    function mySetIntervalOff() {
      clearInterval(mySetInterval);
    }
  </script>

</body>

</html>

Upvotes: 0

CMP
CMP

Reputation: 1220

I use multiple timers this way. It isn't an elegant solution but it works well.

var timerclass = function () {
    this.initialTime = Date.now();
    var t=this;
    var Timer = setInterval(function(){t.checkTime();}, 1000); //start the timer (goes to function checkTime every 1000ms )
    this.timerstart=false;      
}; //end of constructor

timerclass.prototype.StartTheTimer = function(){    
    this.initialTime = Date.now(); //Time right now
    this.timerstart=true;
};      
    
timerclass.prototype.checkTime= function(){ 
    if(this.timerstart==true)
    {
        var timeDifference = Date.now() - this.initialTime; 
        console.log("Time ms: "+timeDifference);        
   }
};  
    
timerclass.prototype.StopTimer= function(){
    this.timerstart=false;
};      
    
module.exports = timerclass;

Then in your main code:

var MyTimerSystem = require(__dirname+'/class.timerclass.js');
var MyFirstTimerObject = new MyTimerSystem(); //First Timer 
var MySecondTimerObject = new MyTimerSystem(); //Second Timer

Stop the timer(s):

MyFirstTimerObject.StopTimer(); //Stop First Timer
MySecondTimerObject.StopTimer(); //Stop Second Timer

Restart the timer(s) from 0ms again:

MyFirstTimerObject.StartTheTimer();  //Start or restart the First timer
MySecondTimerObject.StartTheTimer(); //Start or restart the Second timer

Upvotes: 0

jessegavin
jessegavin

Reputation: 75690

See Working Demo on jsFiddle: http://jsfiddle.net/qHL8Z/3/

$(function() {
  var timer = null,
    interval = 1000,
    value = 0;

  $("#start").click(function() {
    if (timer !== null) return;
    timer = setInterval(function() {
      $("#input").val(++value);
    }, interval);
  });

  $("#stop").click(function() {
    clearInterval(timer);
    timer = null
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="number" id="input" />
<input id="stop" type="button" value="stop" />
<input id="start" type="button" value="start" />

Upvotes: 40

Alnitak
Alnitak

Reputation: 340045

As you've tagged this jQuery ...

First, put IDs on your input buttons and remove the inline handlers:

<input type="number" id="input" />
<input type="button" id="stop" value="stop"/>
<input type="button" id="start" value="start"/>

Then keep all of your state and functions encapsulated in a closure:

EDIT updated for a cleaner implementation, that also addresses @Esailija's concerns about use of setInterval().

$(function() {
    var timer = null;
    var input = document.getElementById('input');

    function tick() {
        ++input.value;
        start();        // restart the timer
    };

    function start() {  // use a one-off timer
        timer = setTimeout(tick, 1000);
    };

    function stop() {
        clearTimeout(timer);
    };

    $('#start').bind("click", start); // use .on in jQuery 1.7+
    $('#stop').bind("click", stop);

    start();  // if you want it to auto-start
});

This ensures that none of your variables leak into global scope, and can't be modified from outside.

(Updated) working demo at http://jsfiddle.net/alnitak/Q6RhG/

Upvotes: 11

Matt Ball
Matt Ball

Reputation: 360016

The reason you're seeing this specific problem:

JSFiddle wraps your code in a function, so start() is not defined in the global scope.

enter image description here


Moral of the story: don't use inline event bindings. Use addEventListener/attachEvent.


Other notes:

Please don't pass strings to setTimeout and setInterval. It's eval in disguise.

Use a function instead, and get cozy with var and white space:

var input = document.getElementById("input"),
  add;

function start() {
  add = setInterval(function() {
    input.value++;
  }, 1000);
}

start();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="number" id="input" />
<input type="button" onclick="clearInterval(add)" value="stop" />
<input type="button" onclick="start()" value="start" />

Upvotes: 28

Jazz Man
Jazz Man

Reputation: 917

add is a local variable not a global variable try this

var add;
var input = document.getElementById("input");

function start() {
  add = setInterval("input.value++", 1000);
}
start();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="number" id="input" />
<input type="button" onclick="clearInterval(add)" value="stop" />
<input type="button" onclick="start()" value="start" />

Upvotes: 5

Esailija
Esailija

Reputation: 140236

(function(){
    var i = 0;
    function stop(){
        clearTimeout(i);
    }

    function start(){
        i = setTimeout( timed, 1000 );
    }

    function timed(){
       document.getElementById("input").value++;
       start();
    }

    window.stop = stop;
    window.start = start;
})()

http://jsfiddle.net/TE3Z2/

Upvotes: 3

Diodeus - James MacFarlane
Diodeus - James MacFarlane

Reputation: 114417

You can't stop a timer function mid-execution. You can only catch it after it completes and prevent it from triggering again.

Upvotes: -4

Related Questions