setInterval只触发一次

时间:2014-07-02 22:39:43

标签: javascript setinterval

我试图创建一个自包含的计时器,其中所有变量都在一个对象中。

在大多数情况下它起作用,但我可以解雇一次。我错过了什么?

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

5 个答案:

答案 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;
};