Stop and restart function setInterval

4

I have a function in javascript that starts a timer. I want to be able to stop, and reset.

jsfiddle example: link

var countms = 0;

function start() {
    var counterms = setInterval(function () {
        countms = countms + 1;
        var id_label_ms = document.getElementById("count_label_ms");
        id_label_ms.innerHTML = countms / 100 + " s";
    }, 1);
}

function stop() {
    clearInterval(counterms);
}
    
asked by anonymous 12.08.2015 / 12:42

4 answers

5

Your idea is on the right path. You must put counterms in a common scope so you can use clearInterval(counterms) .

I also suggest you remove var id_label_ms = document.getElementById("count_label_ms"); out of setInverval so as not to weigh performance. This element needs only once, not every 10 milliseconds.

I've put together other ideas, some suggested in the comments here.

window.onload = function () {
    var countms = 0;
    var counterms;
    var id_label_ms = document.getElementById("count_label_ms");
    var cronometro = {};
    var ativo = false;

    cronometro.start = function () {
        if (ativo) return;
        ativo = true;
        counterms = setInterval(function () {
            countms = countms + 1;
            id_label_ms.innerHTML = countms / 100 + " s";
        }, 10);
    };

    cronometro.stop = function () {
        clearInterval(counterms);
        ativo = false;
    };

    cronometro.reset = function () {
        cronometro.stop();
        ativo = false;
        id_label_ms.innerHTML = countms = 0;
    };

    ['start', 'stop', 'reset'].forEach(function (tipo) {
        var input = document.querySelector('input[name="' + tipo + '"]');
        input.addEventListener('click', cronometro[tipo]);
    });
};

jsFiddle: link

    
12.08.2015 / 12:50
2

In my view, the only problem with the proposed solution is that the setInterval timer is rescheduled at the end of execution, so if the interval is set to 10ms and the time calculation and the label update takes 1ms, then every 10ms timer will delay 1ms.

Then I changed Sergio's fiddle to make this difference more perceptible:

window.addEventListener("load", function() {
  var count_label_tm = document.getElementById("count_label_tm");
  var count_label_ms = document.getElementById("count_label_ms");

  var btStop = document.getElementById("btStop");
  var btReset = document.getElementById("btReset");
  var btStart = document.getElementById("btStart");

  var dtStart;
  var dtAtual;
  var tmAtual = new Date(0);
  var tmAcumulado = new Date(0);

  var interval = 6;
  var countms = 0;
  var counterms;

  btStop.disabled = true;
  btReset.disabled = true;
  btStart.disabled = false;

  btStart.addEventListener("click", function() {
    btStop.disabled = false;
    btReset.disabled = false;
    btStart.disabled = true;
    
    dtStart = new Date();
    counterms = setInterval(function () {
      countms = countms + interval;
      atualizarInputs();
    }, interval);
  });

  btStop.addEventListener("click", function() {
    btStop.disabled = true;
    btReset.disabled = false;
    btStart.disabled = false;
    
    clearInterval(counterms);
    atualizarInputs();
    tmAcumulado = tmAtual;
  });

  btReset.addEventListener("click", function() {   
    btStop.disabled = true;
    btReset.disabled = true;
    btStart.disabled = false;
    
    countms = 0;
    dtStart = null;
    dtAtual = null;
    tmAtual = new Date(0);
    tmAcumulado = new Date(0);
    
    count_label_ms.innerHTML = '';
    count_label_tm.innerHTML = '';
  });

  function atualizarInputs() {
    dtAtual = new Date();
    tmAtual = new Date(tmAcumulado.getTime() + dtAtual.getTime() - dtStart.getTime());
    setHTML();
  } 


  function setHTML() {
    //usando um contador para registrar os ms
    count_label_ms.innerHTML = formatData(new Date(countms));

    //calculando o tempo gasto usando como base a data de inicio, o tempo acumulado e a data atual.
    count_label_tm.innerHTML = formatData(tmAtual);
  }

  function formatData(time) {
    hours = time.getUTCHours().toString();
    minutes = time.getUTCMinutes().toString();
    seconds = time.getUTCSeconds().toString();
    milliseconds = time.getUTCMilliseconds().toString();

    return "00".substring(0, 2 - hours.length) + hours + ":" +
      "00".substring(0, 2 - minutes.length) + minutes + ":" +
      "00".substring(0, 2 - seconds.length) + seconds + "." +
      "000".substring(0, 3 - milliseconds.length) + milliseconds;
  }
});
<div>
  Count: <label id="count_label_ms"></label>
</div>
<div>
  Datas: <label id="count_label_tm"></label>
</div>
<div>
  <input id="btStop" type=button value="stop" />
  <input id="btReset" type=button value="reset" />
  <input id="btStart" type=button value="start" />
</div>

Of course, the time required to execute the serInterval function has increased because of the increase in complexity, but this helps to demonstrate the difference between the two approaches.

    
12.08.2015 / 14:22
2

I made a code change to continue using your same idea.

var countms = 0;

var teste;

    var counterms = function() {
    teste = setInterval(function () {
        countms = countms + 1;
        var id_label_ms = document.getElementById("count_label_ms");
        id_label_ms.innerHTML = countms / 100 + " s";
    }, 1);
    }

function start() {
    counterms();
}

function stop() {
    clearInterval(teste);
}

function reset(){
    clearInterval(teste);

    var id_label_ms = document.getElementById("count_label_ms");
    id_label_ms.innerHTML = 0;
}

HTML

<label id=count_label_ms></label>
<br>
<p>
    <input type=button value="stop" onclick="stop()" />
    <input type=button value="reset" onclick="reset()" />
    <input type=button value="start" onclick="start()" />
</p>
    
13.08.2015 / 00:52
2

To do this, you need to create a variable that transports between methods and allows you to always return the sources:

var countms = 0;
var intervalTxt = null;
function start() {
    var id_label_ms = document.getElementById("count_label_ms");
    if (intervalTxt == null) {
        intervalTxt = setInterval(function() {
            countms = countms + 1;
            id_label_ms.innerHTML =  countms / 100 + " s";
        }, 1);
    }
}

function stop() {
    if (intervalTxt != null) {
        var id_label_ms = document.getElementById("count_label_ms");
        clearInterval(intervalTxt);
        intervalTxt = null;
        id_label_ms.innerHTML =  countms / 100 + " s";
    }
}

function reset() {
    var id_label_ms = document.getElementById("count_label_ms");
    clearInterval(intervalTxt);
    intervalTxt = null;
    id_label_ms.innerHTML = 0 + " s";
}

function resetContinuo() {
    var id_label_ms = document.getElementById("count_label_ms");
    clearInterval(intervalTxt);
    intervalTxt = null;
    countms = 0;
    id_label_ms.innerHTML = 0 + " s";
    start();
}

Here's an example: link
Or if you want something more interesting using object: link
And here is a more elaborate example: link

    
12.08.2015 / 15:18