Javascript секундомер с шагом в миллисекунды

1

Я пытаюсь собрать секундомер с использованием JavaScript. У меня есть дата для заполнения правильной информацией, но мой секундомер не работает. Я нажимаю кнопку "Пуск" и цифры никогда не перемещаются с 0, я бы хотел, чтобы он увеличивался в MS без секунд. У меня есть код для JS и HTML. HTML функционирует так, как должно, но JS нет. Я очень зелёный для мира JavaScript, и я посмотрел и посмотрел, и мне не удалось найти решение, которое было бы полезно для меня. Спасибо за вашу помощь.

"use strict";
var $ = function(id) { return document.getElementById(id); };

var stopwatchTimer;

var elapsedMinutes = 0;

var elapsedSeconds = 0;

var elapsedMilliseconds = 0;

var displayCurrentTime = function() {

  var now = new Date();

var hours = now.getHours();

var ampm = "AM";
if (hours > 12) { 

hours = hours - 12;

ampm = "PM";


} else { 

 switch (hours) {

case 12:

 ampm = "PM";

break;

case 0:  

 hours = 12;

ampm = "AM";

 }

 }


$("hours").firstChild.nodeValue = hours;

$("minutes").firstChild.nodeValue = padSingleDigit(now.getMinutes());

$("seconds").firstChild.nodeValue = padSingleDigit(now.getSeconds());

$("ampm").firstChild.nodeValue = ampm;

};

var padSingleDigit = function(num) {

if (num < 10) { return "0" + num; }

else { return num; }

};

var tickStopwatch = function() {    
// I also need to increment in 10 milliseconds increments but unsure if I //have this right


var ms=0;
var sec=0;
var min=0;

var frame= function() {
If(ms==1000)
        ms=0;
        sec++;
}
if(sec==60) {
        sec=0;
        min++;

document.getElementById("s_seconds").innerHTML = valueOf(sec);
document.getElementById("s_minutes").innerHTML = valueOf(min);
document.getElementById("s_ms").innerHTML = valueOf(ms);
}

};

var startStopwatch = function(evt) {

};

var stopStopwatch = function(evt) {

};

var resetStopwatch = function(evt) {

};
window.onload = function() {    

displayCurrentTime();    
setInterval(tickStopwatch, 1000);
};
"use strict"; //evt is in a separate file
var evt = {
    attach: function(node, eventName, func) {

    },
    detach: function(node, eventName, func) {

    },
    preventDefault: function(e) {

    }
};


    <!DOCTYPE html> 
    <html> 
    <head> 
    <meta charset="UTF-8"> 
    <title>Clock</title> 
    <link rel="stylesheet" href="clock.css"> 

    <script src="library_event.js"></script> 

    <script src="clock.js"></script> 

    </head> 
    <body> 
    <main> 
    <h1>Digital clock with stopwatch</h1> 
    <fieldset> 
    <legend>Clock</legend> 
    <span id="hours">&nbsp;</span>: 
    <span id="minutes">&nbsp;</span>: 
    <span id="seconds">&nbsp;</span>&nbsp; 
    <span id="ampm">&nbsp;</span> 
    </fieldset> 

    <fieldset> 
    <legend>Stop Watch</legend> 
    <a href="#" id="start">Start</a>&nbsp; 

    <a href="#" id="stop">Stop</a>&nbsp; 

    <a href="#" id="reset">Reset</a>&nbsp; 

    <span id="s_minutes">00</span>: 
    <span id="s_seconds">00</span>: 
    <span id="s_ms">000</span> 
    </fieldset> 
    </main> 
    </body> 
    </html>
Теги:
stopwatch

3 ответа

0

Если вы постепенно обновляете значения ms, seconds, minutes вы никогда не будете точными. Вы будете терять время с каждым обновлением. Просто нет интервала, который может работать с такой скоростью и точностью в JS.

Вместо этого вычислить их из внутренних часов

let offset = 0,
  paused = true;
  
function startStopwatch(evt) {
  if (paused) {
    paused = false;
    offset -= Date.now();
    requestAnimationFrame(render);
  }
}

function stopStopwatch(evt) {
  if (!paused) {
    paused = true;
    offset += Date.now();
  }
}

function resetStopwatch(evt) {
  offset = 0;
  paused = true;
}

function format(value, scale, modulo, padding) {
  value = Math.floor(value / scale) % modulo;
  return value.toString().padStart(padding, 0);
}

function render() {
  var value = paused ? offset : Date.now() + offset;

  document.querySelector('#s_ms').textContent = format(value, 1, 1000, 3);
  document.querySelector('#s_seconds').textContent = format(value, 1000, 60, 2);
  document.querySelector('#s_minutes').textContent = format(value, 60000, 60, 2);
  
  if(!paused) {
    requestAnimationFrame(render);
  }
}

render();
<fieldset>
  <legend>Stop Watch</legend>
  <a href="#" id="start" onclick="startStopwatch()">Start</a>&nbsp;

  <a href="#" id="stop" onclick="stopStopwatch()">Stop</a>&nbsp;

  <a href="#" id="reset" onclick="resetStopwatch()">Reset</a>&nbsp;

  <span id="s_minutes">00</span>:
  <span id="s_seconds">00</span>:
  <span id="s_ms">000</span>
</fieldset>

offset сохраняет два значения: при paused он сохраняет значение, на котором вы остановились, в противном случае он сохраняет смещение, которое вы должны добавить в Date.now() чтобы вычислить значение.

Значение - это время в мс, вычисление секунд и минут из него - основная арифметика.

  • 0
    @marc_s, спасибо
0

Заменить эту строку:

setInterval(tickStopwatch, 1000);

С этой строкой:

setInterval(tickStopwatch, 1);
  • 0
    минимальный интервал обновления для setinterval и setTimeout составляет около 10 мс, а точность зависит от нагрузки.
0

Функция интервалов устанавливается на один раз на 1000 мс (или 1 сек), что не даст вам разрешения 1 мс. Фактически, лучшее, что вы можете сделать, это разрешение 10 мс с помощью setInterval. Вам также необходимо увеличить счетчик, который вы в настоящее время не выполняете.

Пытаться:

setInterval(tickStopwatch, 10);

var ms = 0;
var tickStopwatch = function() {    
   var ms += 10;
   // rest of your logic
}
  • 0
    setInterval не поддерживает разрешение 1 мс. минимум 10 мс.
  • 0
    Да вы правы. Обновил мой ответ. Благодарю.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню