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?
-
2This might give you more of what you are looking for: jsfiddle.net/4ktEG/13Jared Farrish– Jared Farrish2011年07月31日 16:10:15 +00:00Commented Jul 31, 2011 at 16:10
6 Answers 6
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();
1 Comment
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/
Comments
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();
1 Comment
When you say
setTimeout(this.clock(), 1000); //the clock method will be called right away.
Use this instead
setTimeout(this.clock, 1000);
Comments
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.
2 Comments
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();