我试图创建一个自包含的计时器,其中所有变量都在一个对象中。
在大多数情况下它起作用,但我可以解雇一次。我错过了什么?
function Countdown()
{
this.appId = null;
this.timerId = null;
this.seconds = null;
this.decrementCounter = function (instant)
{
if (instant == null)
return;
instant.tick();
if (instant.seconds === 0)
{
instant.tickEnd();
instant.stop();
}
instant.seconds--;
};
this.tick = function ()
{
var xx = this.appId
};
this.tickEnd = function ()
{
var xx = this.appId
};
this.start = function ()
{
clearInterval(this.timerId);
this.timerId = setInterval(this.decrementCounter(this), 1000);
};
this.stop = function ()
{
clearInterval(this.timerId);
};
}
答案 0 :(得分:3)
我稍微修改了您的代码并将包含setInterval
的行更改为:
this.timerId = setInterval((function(scope) {return function() {scope.decrementCounter(scope);};})(this), 1000);
setInterval
内部运行的函数在window
范围内运行。它只运行一次,因为你没有传递函数本身只是它的结果。您需要返回实际函数或传递一个调用它的匿名函数。
jsfiddle demo:http://jsfiddle.net/2gLdL/1/
答案 1 :(得分:0)
您正在调用该函数,而不是分配引用
this.timerId = setInterval(this.decrementCounter(this), 1000);
似乎很奇怪你传递“这个”作为一个论点......
使用bind()
this.timerId = setInterval(this.decrementCounter.bind(this, this), 1000);
或关闭
var that = this;
this.timerId = setInterval(function(){that.decrementCounter(that); }, 1000);
答案 2 :(得分:0)
在下面的代码中:
this.timerId = setInterval(this.decrementCounter(this), 1000);
您正在立即执行此操作:
this.decrementCounter(this)
所以它的返回值是每秒由setInterval调用的。通常你会希望传递一个函数闭包,如下所示:
var _this = this; //make sure your variable is available in the scope that follows
this.timerId = setInterval(function() { this.decrementCounter(_this); }, 1000);
然后,当你的计时器被执行时,它被调用的函数,然后该函数执行你想要的。另一个选择是将第一个参数作为字符串传递,例如“callAFunction('blah')”,它将每秒进行一次评估并执行,但我相信以上是你想要的。
答案 3 :(得分:0)
试试这个:
setInterval(function(){Countdown()},500);
答案 4 :(得分:-1)
我提供了一个answer to another question来创建一个简单的秒表。
您可以稍微修改代码以倒计时而不是向上。
<强> Here's a jsbin demo 强>
原始摘录
var Stopwatch = function(elem, options) {
var timer = createTimer(),
startButton = createButton("start", start),
stopButton = createButton("stop", stop),
resetButton = createButton("reset", reset),
offset,
clock,
interval;
// default options
options = options || {};
options.delay = options.delay || 1;
// append elements
elem.appendChild(timer);
elem.appendChild(startButton);
elem.appendChild(stopButton);
elem.appendChild(resetButton);
// initialize
reset();
// private functions
function createTimer() {
return document.createElement("span");
}
function createButton(action, handler) {
var a = document.createElement("a");
a.href = "#" + action;
a.innerHTML = action;
a.addEventListener("click", function(event) {
handler();
event.preventDefault();
});
return a;
}
function start() {
if (!interval) {
offset = Date.now();
interval = setInterval(update, options.delay);
}
}
function stop() {
if (interval) {
clearInterval(interval);
interval = null;
}
}
function reset() {
clock = 0;
render();
}
function update() {
clock += delta();
render();
}
function render() {
timer.innerHTML = clock/1000;
}
function delta() {
var now = Date.now(),
d = now - offset;
offset = now;
return d;
}
// public API
this.start = start;
this.stop = stop;
this.reset = reset;
};