1

I am programming a little timer. The code is as follows:

var counter = {
 seconds: 100,
 clock: function () {
 $('input').val(this.seconds);
 this.seconds -= 1;
 setTimeout(this.clock(), 1000);
 }
};
counter.clock();

with a working example on http://jsfiddle.net/4ktEG/

Somehow each time I run the code I get a different answer. What is the problem?

asked Jul 31, 2011 at 16:05
1
  • 2
    This might give you more of what you are looking for: jsfiddle.net/4ktEG/13 Commented Jul 31, 2011 at 16:10

6 Answers 6

7

This does the countdown you're looking for.

var counter = {
 seconds: 100,
 clock: function () {
 $('input').val(this.seconds);
 this.seconds -= 1;
 setTimeout(function(){counter.clock()}, 1000);
 }
};
counter.clock();

http://jsfiddle.net/4ktEG/13/

answered Jul 31, 2011 at 16:11
Sign up to request clarification or add additional context in comments.

1 Comment

No problem. I thought initially something else was going on, which was I posted it as a comment instead of an answer.
1

jQuery has the jQuery.proxy()[docs] method for binding the this value.

setTimeout($.proxy(counter,'clock'), 1000);

The $.proxy will return a function that invokes counter.clock with counter bound as the this value.


Or you can use it like this to permanently bind counter to counter.clock:

var counter = {
 seconds: 100
};
counter.clock = $.proxy( function () {
 $('input').val(this.seconds);
 this.seconds -= 1;
 setTimeout(this.clock, 1000);
}, counter);
counter.clock();

Example: http://jsfiddle.net/bmYAN/

answered Jul 31, 2011 at 16:33

Comments

0

If you want the input to show "100", then disappear when the setTimeout is called, then you have to take out the brackets on "this.clock()"

Therefor:

var counter = {
seconds: 100,
clock: function () {
 $('input').val(this.seconds);
 this.seconds -= 1;
 setTimeout(this.clock, 1000);
}
};
counter.clock();
answered Jul 31, 2011 at 16:11

1 Comment

That's not what I want. I want a counter that goes 100, 99, 98, etc.
0

When you say

setTimeout(this.clock(), 1000); //the clock method will be called right away.

Use this instead

setTimeout(this.clock, 1000); 
answered Jul 31, 2011 at 16:13

Comments

0

Use:

var counter = {
 seconds: 100,
 clock: function () {
 $('input').val(counter.seconds);
 counter.seconds -= 1;
 setTimeout(counter.clock, 1000);
 }
};
counter.clock();

You used "this" inside a function, what you want is to refer to the "counter" object.

answered Jul 31, 2011 at 16:10

2 Comments

I still doesn't do what I want. It shows 100, and then nothing.
and how is it different? explain please!
0

The timeout will execute in a global context. Hence the 'this' inside the handler will refer to the global context. You have to bind the function to the wanted context to achieve the desired result. Look into function.call or function.apply which take a context parameter.

var counter = {
 seconds: 100,
 clock: function () {
 $('input').val(this.seconds);
 this.seconds -= 1;
 var closure = function() {
 counter.clock.call(counter);
 };
 setTimeout(closure, 1000);
 }
};
counter.clock();
answered Jul 31, 2011 at 16:19

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.