Javascript секундомер с шагом в миллисекунды - PullRequest
0 голосов
/ 26 октября 2018

Я пытаюсь собрать секундомер, используя 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>

Ответы [ 3 ]

0 голосов
/ 26 октября 2018

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

setInterval(tickStopwatch, 1000);

На эту строку:

setInterval(tickStopwatch, 1);
0 голосов
/ 26 октября 2018

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

Вместо этого рассчитайте их по внутренним часам

let offset = 0,
  paused = true;

render();
  
function startStopwatch(evt) {
  if (paused) {
    paused = false;
    offset -= Date.now();
    render();
  }
}

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

function resetStopwatch(evt) {
  if (paused) {
    offset = 0;
    render();
  } else {
    offset = -Date.now();
  }
}

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);
  }
}
<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 голосов
/ 26 октября 2018

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

Попробуйте:

setInterval(tickStopwatch, 10);

var ms = 0;
var tickStopwatch = function() {    
   var ms += 10;
   // rest of your logic
}
...