в вашей строке var milliseconds = Math.floor((difference % (1000 * 60)) / 100);
неверный расчет. Метод getTime
объекта Date
уже возвращает значение в миллисекундах.
var startTimerButton = document.querySelector('.startTimer');
var pauseTimerButton = document.querySelector('.pauseTimer');
var timerDisplay = document.querySelector('.timer');
var startTime;
var updatedTime;
var difference;
var tInterval;
var savedTime;
var paused = 0;
var running = 0;
function startTimer() {
if (!running) {
startTime = new Date().getTime();
tInterval = setInterval(getShowTime, 1);
paused = 0;
running = 1;
startTimerButton.style.cursor = "auto";
pauseTimerButton.style.cursor = "pointer";
}
}
function pauseTimer() {
if (!difference) {
// if timer never started, don't allow pause button to do anything
} else if (!paused) {
clearInterval(tInterval);
savedTime = difference;
paused = 1;
running = 0;
pauseTimerButton.classList.add('lighter');
startTimerButton.style.cursor = "pointer";
pauseTimerButton.style.cursor = "auto";
} else {}
}
function resetTimer() {
document.location.reload();
}
function getShowTime() {
updatedTime = new Date().getTime();
if (savedTime) {
difference = (updatedTime - startTime) + savedTime;
} else {
difference = updatedTime - startTime;
}
var hours = Math.floor((difference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((difference % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((difference % (1000 * 60)) / 1000);
//here!
var milliseconds = difference % 1000; //<<<<< this line
//var milliseconds = Math.floor((difference % (1000 * 60)) / 100); //<<<<< instead of this
hours = (hours < 10) ? "0" + hours : hours;
minutes = (minutes < 10) ? "0" + minutes : minutes;
seconds = (seconds < 10) ? "0" + seconds : seconds;
milliseconds = (milliseconds < 100) ? (milliseconds < 10) ? "00" + milliseconds : "0" + milliseconds : milliseconds;
timerDisplay.innerHTML = hours + ':' + minutes + ':' + seconds + ':' + milliseconds;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.1/css/all.min.css" rel="stylesheet" />
<h1>Stopwatch</h1>
<div class="timer">00:00:00:00</div>
<div class="startTimer reset" onclick="startTimer()"> Start
<i class="fas fa-play"></i>
</div>
<div class="pauseTimer reset" onclick="pauseTimer()"> Stop
<i class="fas fa-pause"></i>
</div>
<div class="resetTimer reset" onclick="resetTimer()">Reset</div>
Я как можно меньше менял код, но это далеко не оптимальное решение, код довольно сложно читать и может содержать слишком много шагов .
Главный вывод здесь заключается в том, что вам не нужно преобразовывать значение времени в миллисекундах, если оно уже указано в миллисекундах.
Вот фрагмент кода, который был бы больше читаемый:
//*********************************
//constants, state variables and object declarations
//*********************************
const MS_PER_SEC = 1000;
const MS_PER_MIN = MS_PER_SEC * 60;
const MS_PER_HOUR = MS_PER_MIN * 60;
const MS_PER_DAY = MS_PER_HOUR * 24;
var running = false;
var startTime = null;
var pausedTimer = null; //elapsed milliseconds already in timer
var timerObject = { //encapsulating data and methods (preferrably in a different file)
hours: 0,
minutes: 0,
seconds: 0,
milliseconds: 0,
clearTimer: function() {
this.hours = 0;
this.minutes = 0;
this.seconds = 0;
this.milliseconds = 0;
},
setTimer: function(ms) {
this.hours = Math.floor(ms % (MS_PER_DAY) / MS_PER_HOUR);
this.minutes = Math.floor(ms % (MS_PER_HOUR) / MS_PER_MIN);
this.seconds = Math.floor(ms % (MS_PER_MIN) / MS_PER_SEC);
this.milliseconds = ms % MS_PER_SEC;
},
formatTime: function() {
return [
("" + this.hours).padStart(2, '0'),
("" + this.minutes).padStart(2, '0'),
("" + this.seconds).padStart(2, '0'),
].join(":") +
"." + ('' + this.milliseconds).padStart(3, '0');
}
};
//*********************************
//Actual functions used in the page
//*********************************
function startTimer() {
if (!running) { //ignore if already running
if (startTime != null && pausedTimer != null) {
//if timer was paused, both values should be != null
startTime.setTime((new Date()).getTime() - pausedTimer);
pausedTimer = null; //not necessary, but I like to make stuff crash when I make a mistake
} else {
//consider the timer as new or reset otherwise
startTime = new Date();
}
running = true;
updateTimer();
}
}
function pauseTimer() {
if (running) {
running = false;
var currentTime = new Date();
pausedTimer = currentTime.getTime() - startTime.getTime();
}
updateTimer();
}
function resetTimer() {
running = false;
startTime = null;
pausedTimer = null;
timerObject.clearTimer();
updateTimer();
}
function updateTimer() {
if (running) {
var currentTime = new Date();
var difference = currentTime.getTime() - startTime.getTime();
timerObject.setTimer(difference);
setTimeout(updateTimer, 31);
}
var timerDisplay = document.getElementById("timer");
timerDisplay.innerHTML = timerObject.formatTime();
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.1/css/all.min.css" rel="stylesheet" />
<h1>Stopwatch</h1>
<div class="timer" id="timer">
00:00:00:000
</div>
<div class="startTimer reset" onclick="startTimer()">
Start <i class="fas fa-play"></i>
</div>
<div class="pauseTimer reset" onclick="pauseTimer()">
Pause <i class="fas fa-pause"></i>
</div>
<div class="resetTimer reset" onclick="resetTimer()">
Reset
</div>