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.

6 Answers 6

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(); }); 
Sign up to request clarification or add additional context in comments.

Comments

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

1 Comment

could probably not bother with var that at all
2

Clear the timer every time it's initalized, that way all you have to do is call the function again to reset the timer :

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

FIDDLE

Comments

2

You could re-write your myTimer() function like so:

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

Now, whenever you call myTimer(), the setInterval gets reset.

Comments

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

2 Comments

It is, at first... but nowadays I'm writing so much JS, thousands of lines (no jQuery, but pure JS) and you really get used to it. just ignore the many brackets and focus on the return function lines, usually just above them, the anonymous function of the closure starts, and below, you see the arguments. This approach also allows you to pass DOM references as an argument. as this code stands, on each interval $('#timer').text(sec--); scans the dom all over again, whereas passing the reference happens only once, regardless of the number of interval calls: big performance benefit
i feel ya, just coming from coffee script, nice formatting for my eyes, and all that magic wrapping.
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/

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.