Greetings. Faced a problem in the implementation of a timer with a pause. Pause does not remove the interval, although it should.

http://jsfiddle.net/acqhr6y8/

function Timer(callback, delay) { var start = new Date().getTime(); var countDownDate = start + delay; var timerId, start, remaining = delay; this.pause = function() { window.clearTimeout(timerId); remaining -= new Date() - start; clearInterval(this.cutdown); }; this.resume = function() { start = new Date(); window.clearTimeout(timerId); timerId = window.setTimeout(callback, remaining); setInterval(this.cutdown, 1000); }; this.cutdown = function() { remaining = remaining - 1000; minutes = Math.floor((remaining % (1000 * 60 * 60)) / (1000 * 60)); seconds = Math.floor((remaining % (1000 * 60)) / 1000); (remaining < 0) ? clearInterval(this.cutdown) : $("#time").html(minutes + "m " + seconds + "s"); }; this.resume(); } var timer = new Timer(function() { $("#status").html("Stoped"); }, 30000); $("#pause").click(function() { timer.pause(); }); $("#resume").click(function() { timer.resume(); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <div id="time"> </div> <div id="status"> Up </div> <div id="pause"> pause </div> <div id="resume"> resume </div> 

Most likely I messed up with an interval, but I could not understand where.

  • clearInterval as well as clearTimeout accepts a timer id. and you pass it a function. In turn, you never save the result of setInterval(this.cutdown, 1000); which should be passed to clearInterval - Grundy

2 answers 2

clearInterval , like clearTimeout , accepts a timer id .

In the code in question, the function is passed to it.

In turn, the result of setInterval(this.cutdown, 1000); not saved anywhere setInterval(this.cutdown, 1000); which should be passed to clearInterval


For the solution, you need to add an additional variable to store the interval and use it similarly to the existing timerId .

In addition, there seems to be a logical error in the pause method. It does not need to change remaining trying to associate with local time, since this is a state of the timer and it should not change while the timer is stopped.

 function Timer(callback, delay) { var timerId, intervalId, start, remaining = delay; this.pause = function() { window.clearTimeout(timerId); clearInterval(intervalId); }; this.resume = function() { window.clearTimeout(timerId); clearInterval(intervalId); timerId = window.setTimeout(callback, remaining); intervalId = setInterval(this.cutdown, 1000); }; this.cutdown = function() { remaining = remaining - 1000; minutes = Math.floor((remaining % (1000 * 60 * 60)) / (1000 * 60)); seconds = Math.floor((remaining % (1000 * 60)) / 1000); (remaining < 0) ? clearInterval(intervalId): $("#time").html(minutes + "m " + seconds + "s"); }; this.resume(); } var timer = new Timer(function() { $("#status").html("Stoped"); }, 30000); $("#pause").click(function() { timer.pause(); }); $("#resume").click(function() { timer.resume(); }); 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <div id="time"> </div> <div id="status"> Up </div> <div id="pause"> pause </div> <div id="resume"> resume </div> 

  • You did not take into account the fact that when you click on "resume", a timer is started which will not stop the "pause". you can also use the "resume" button, you can start several timers and the counter will decrease faster and the script will not stop at all .. just will not display the time <0 - Akubik
  • one
    @Akubik, yes, I missed the call clearInterval - Grundy
  • that's good now - Akubik
  • ... ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ id Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π°. Π’ ΠΊΠΎΠ΄Π΅ Π² вопросС Π΅ΠΌΡƒ пСрСдаСтся функция ... ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ id Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π°. Π’ ΠΊΠΎΠ΄Π΅ Π² вопросС Π΅ΠΌΡƒ пСрСдаСтся функция is ... ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ id Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π°. Π’ ΠΊΠΎΠ΄Π΅ Π² вопросС Π΅ΠΌΡƒ пСрСдаСтся функция - these are the minuses of dynamic typing. - ΠΎΠΊΡ‚
  • @Arhad, I think the problem is not in the hammer :-) - Grundy

Try this syntax

 var timerId = setTimeout(...); clearTimeout(timerId); 

the fact is that you need to deal with the transfer of parameters, time and scope of variables (as mentioned above) ... I do not know what your task is there, but you can do it easier, for example, do not stop the timer, but change the increment variable - delta :

 <!doctype html> <html> <head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script> <script> function Timer(callback, delay) { var start = new Date().getTime(); var timerId, remaining = delay, delta =1000; this.pause = function() { $("#status").html("Paused"); delta = 0; }; this.resume = function() { $("#status").html("Up"); delta = 1000; }; this.cutdown = function() { remaining = remaining - delta; minutes = Math.floor((remaining % (1000 * 60 * 60)) / (1000 * 60)); seconds = Math.floor((remaining % (1000 * 60)) / 1000); $("#time").html(minutes + "m " + seconds + "s"); if (remaining <= 0) {clearInterval(timerId);callback();} }; timerId = setInterval(this.cutdown, 1000); } </script> </head> <body> <div id="time"> </div> <div id="status"> Up </div> <div id="pause"> pause </div> <div id="resume"> resume </div> <script> var timer = new Timer(function() { $("#status").html("Stoped"); }, 30000); $("#pause").click(function() { timer.pause(); }); $("#resume").click(function() { timer.resume(); }); </script> </body> </html> 

Or do you still need to work with starting and stopping timers? then, ideally, you will need to take into account the time of the script itself, the browser load and their features