簡體   English   中英

setInterval僅觸發一次

[英]setInterval fires only once

我正在嘗試創建一個自包含計時器,其中所有變量都在一個對象內。

在大多數情況下,它都能正常工作,但我可以將其觸發一次。 我想念什么?

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

我對代碼進行了一些修改,並將包含setInterval的行更改為:

this.timerId = setInterval((function(scope) {return function() {scope.decrementCounter(scope);};})(this), 1000);

這些函數在setInterval內部運行,並在window范圍內運行。 它僅運行一次,因為您不會僅僅傳遞函數本身的結果。 您需要返回實際函數或傳遞調用它的匿名函數。

jsfiddle演示: http : //jsfiddle.net/2gLdL/1/

您正在調用函數,而不是分配引用

this.timerId = setInterval(this.decrementCounter(this), 1000); 

您似乎以“ this”作為參數傳遞很奇怪。

使用bind()

this.timerId = setInterval(this.decrementCounter.bind(this, this), 1000); 

或關閉

var that = this;
this.timerId = setInterval(function(){that.decrementCounter(that); }, 1000); 

在下面的代碼中:

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')”,該字符串將每秒進行評估並執行,但我相信上面就是您想要的。

嘗試這個:

setInterval(function(){Countdown()},500);

為另一個創建簡單秒表的問題提供了答案

您可以稍微修改代碼以遞減計數而不是遞增計數。

這是一個jsbin演示


原始片段

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM