Alex Rivera | Logout

jQuery reset setInterval timer

Asked 2012-08-02T15:45:03.000
9

My Jquery:

function myTimer() {
    var sec = 15
    var timer = setInterval(function() { 
    $('#timer').text(sec--);
    if (sec == -1) {
      clearInterval(timer);
      alert('done');
     } 
    }   , 1000);

}

$("#knap").click(function() {
    myTimer();
});

$("#reset").click(function() {
// set timer to 15 sec again.. 
});

I want the timer to be reset when clicked on #reset.

Edit
Report

4 Answers

14

You need to leave your "timer" variable in a scope that is available the next time you call the myTimer function so you can clear the existing interval and reset it with a new interval. Try:

var timer;
functionn myTimer() {
    var sec = 15
    clearInterval(timer);
    timer = setInterval(function() { 
    $('#timer').text(sec--);
    if (sec == -1) {
      clearInterval(timer);
      alert('done');
     } 
    }   , 1000);

}

$("#knap").click(function() {
    myTimer();
});

$("#reset").click(function() {
   myTimer();
});
answered 2012-08-02T15:47:22.630
8

or you could do something along these lines:

var myTimer = function(){
    var that = this,
        time = 15,
        timer;
    that.set = function() {
        console.log('setting up timer');
        timer = setInterval(function(){
            console.log('running time: ' + time);
        },1000);
    }
    that.reset = function(){
        console.log('clearing timer');
        clearInterval(timer);
    }
    return that;
}();

and run when you need to:

myTimer.set(); myTimer.reset();

answered 2012-08-02T16:09:55.597
0

Here's an approach that is more in tune with the way JS was designed (as a functional language for those who still don't know). Rather than relying on a global variable, use a closure:

$("#knap").click(function start()//named callback to bind && unbind:
{
    $(this).unbind('click');//no need to start when started
    $("#reset").unbind('click').click((function(timer)
    {//timer is in scope thanks to closure
       return function()
       {//resets timer
          clearInterval(timer);
          timer = null;
          $('#knap').click(start);//bind the start again
          //alternatively, you could change the start button to a reset button on click and vice versa
       }
    })(setInterval((function(sec)
       {
           return function()
           {
               $('#timer').text(sec--);
               if (sec === -1)
               {
                   $('#reset').click();//stops interval
                   $('#reset').unbind('click');//no more need for the event
                   alert('done');
               }//here's the interval counter: 15, passed as argument to closure
           })(15),1000)));//set interval returns timer id, passed as argument to closure
});

Now I will admit this is rather messy (and untested) but this way there reset event is only available when it's necessary, and you're not using any globals. But crucially, this is where JS's power lies: functions as 1st class objects, passing them as arguments and return values... just go function-crazy :)

I've set up a working Fiddle, too

answered 2012-08-02T16:10:10.420
0

You could also use a jQuery timer plugin, then you don't need to pass around the Variable.

Plugin: http://archive.plugins.jquery.com/project/timers

Example for the plugin: http://blog.agrafix.net/2011/10/javascript-timers-mit-jquery/

answered 2012-08-28T21:03:56.243

Your Answer