Đồng hồ Javascript đếm qua 60 phút và giây
Tôi đã tạo đồng hồ Javascript, khi giây và phút chạm 60, nó sẽ đếm trên 60 và tiếp tục ...
function increment(){
if(running == 1){
setTimeout(function(){
Dtime++;
var hours = Math.floor(Dtime / 10 / 3600);
if(hours <= 9){
hours = "0" + hours;
}
var mins = Math.floor(Dtime / 10 / 60);
if(mins <= 9){
mins = "0" + mins;
}
var secs = Math.floor(Dtime / 10);
if(secs <= 9){
secs = "0" + secs;
}
document.getElementById("outputt").innerHTML = hours + ":" + mins + ":" + secs;
increment();
}, 100);
}
}
var Dtime=0;
var running = 1;
increment();
<div id="outputt" class="timerClock" value="00:00:00">00:00:00</div>
Về cơ bản, đồng hồ đếm qua 60 phút và giây, tôi muốn điều này đặt lại về 0 thay vì chạm 60. Tôi không có thời gian để kiểm tra giờ mặc dù tôi chắc chắn rằng nó cũng sẽ qua 24.
Xin vui lòng ai đó có thể giải thích làm thế nào điều này sẽ được thực hiện? Tôi chắc chắn rằng nó rất đơn giản nhưng tôi đã cố gắng đấu tranh với nó một thời gian dài và đang cảm thấy thất vọng.
Trả lời
Bạn có thể sử dụng toán tử phần dư ( %) để chuyển về 0 khi một số chuyển qua 60.
Ví dụ
59 % 60 === 5960 % 60 === 061 % 60 === 1
Vì vậy, mã của bạn sẽ giống như sau:
function increment() {
if (running == 1) {
setTimeout(function() {
Dtime++;
var hours = Math.floor(Dtime / 10 / 3600);
if (hours <= 9) {
hours = "0" + hours;
}
var mins = Math.floor(Dtime / 10 / 60) % 60; // Remainder operator
if (mins <= 9) {
mins = "0" + mins;
}
var secs = Math.floor(Dtime / 10) % 60; // Remainder operator
if (secs <= 9) {
secs = "0" + secs;
}
document.getElementById("outputt").innerHTML = hours + ":" + mins + ":" + secs;
increment();
}, 100);
}
}
var running = 1;
var Dtime = 35980; //Setting it just under 1 hour for testing purposes
increment();
<div id="outputt" class="timerClock" value="00:00:00">00:00:00</div>
Xin lưu ý rằng bộ đếm thời gian này có thể trôi theo thời gian. Để biết tại sao và làm thế nào bạn có thể giải quyết điều đó, hãy xem Cách tạo bộ đếm thời gian chính xác trong javascript?
Bạn không thể tin rằng setTimeout hoặc setInterval sẽ thực thi trong chính xác X mili giây. Hãy xem video sau đây về các vòng lặp sự kiện để hiểu lý do. Đó là điều bạn nên biết khi lập trình javascript.
Thay vào đó, những gì bạn cần làm là cập nhật phần tử đầu ra mỗi khi màn hình sửa lại, điều này bạn có thể làm với requestAnimationFrame . Bạn cần lưu trữ thời điểm đồng hồ bắt đầu, có thể được thực hiện bằng mili giây, sau đó tính toán chênh lệch giữa thời gian bắt đầu và thời gian hiện tại (với Date.now()) khi cửa sổ chuẩn bị sơn lại. requestAnimationFramenhận một cuộc gọi lại làm tham số, đây phải là phương thức cập nhật phần tử đầu ra của bạn.
CHỈNH SỬA: Tôi đã tăng tốc bộ đếm thời gian để hiển thị trường hợp đặt lại phút và giây.
const outputElement = document.getElementById("output");
var startTime = 0;
function startTimer() {
startTime = Date.now();
updateTimer();
}
function updateTimer() {
let differenceInMillis = Date.now() - startTime;
let {hours, minutes, seconds} = calculateTime(differenceInMillis);
let timeStr = `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`;
outputElement.innerText = timeStr;
requestAnimationFrame(updateTimer);
}
function calculateTime(timeInMillis) {
const SECONDS = 10; // should be 1000 - only 10 to speed up the timer
const MINUTES = 60;
const HOURS = 60;
const RESET = 60;
let hours = Math.floor(timeInMillis / SECONDS / MINUTES / HOURS);
let minutes = Math.floor(timeInMillis / SECONDS / MINUTES) % RESET;
let seconds = Math.floor(timeInMillis / SECONDS) % RESET;
return {hours, minutes, seconds};
}
function pad(time) {
return time.toString().padStart(2, '0');
}
startTimer();
<div id="output" class="timerClock" value="00:00:00">00:00:00</div>
Bạn có thể sử dụng String.padStartđể chèn 0biểu tượng cho các giá trị kỹ thuật số.
Và thay vì gọi hàm bên trong setTimeoutcho recursive, bạn có thể sử dụng setInterval. Để xóa trình xử lý thời gian, bạn có thể sử dụng clearInterval.
Và tham số thứ hai của setIntervallà milisecondsgiá trị, do đó, để đếm thời gian theo giây, nó sẽ tốt để đặt 1000 - 1 second.
let Dtime = 0;
setInterval(function() {
Dtime++;
const hours = Math.floor(Dtime / 3600).toString();
const mins = Math.floor((Dtime % 3600) / 60).toString();
const secs = (Dtime % 60).toString();
document.getElementById("outputt").innerHTML = hours.padStart(2, '0') + ":" + mins.padStart(2, '0') + ":" + secs.padStart(2, '0');
}, 1000);
<div id="outputt" class="timerClock" value="00:00:00">00:00:00</div>
Điều này hơi quá mức cần thiết cho những gì bạn đang làm, nhưng nó có một phương pháp hay để định dạng chuỗi thời gian. Nó cũng chỉ ra cách sử dụng Date.now () để theo dõi chênh lệch múi giờ.
class StopWatch {
startTime = 0
previousDuration = 0
currentDuration = 0
timer = null;
listeners = {
update: [],
mark: [],
reset: []
}
marks = []
start() {
if (this.timer) return;
this.previousDuration += this.currentDuration;
this.currentDuration = 0;
this.startTime = Date.now();
this.run();
}
stop() {
if (!this.timer) return;
this.setDuration();
window.clearTimeout(this.timer);
this.timer = null;
}
run() {
this.setDuration();
this.timer = window.setTimeout(this.run.bind(this), 10);
}
setDuration () {
this.currentDuration = Date.now() - this.startTime;
this.trigger('update');
}
trigger (evtName) {
const details = {
time: this.msToTime(this.currentDuration + this.previousDuration),
marks: [...this.marks]
};
this.listeners[evtName].forEach(cb => cb(details));
}
mark () {
this.marks.push(this.msToTime(this.currentDuration + this.previousDuration));
this.trigger('mark');
}
reset() {
if (this.timer) window.clearTimeout(this.timer);
this.currentDuration = 0;
this.previousDuration = 0;
this.marks = [];
this.trigger('update');
this.trigger('reset');
}
on (event, callback) {
var arr = this.listeners[event];
if (!arr) throw(`unknown event ${event}`);
arr.push(callback);
return this;
}
msToTime (duration) {
let milliseconds = parseInt((duration % 1000));
let seconds = Math.floor((duration / 1000) % 60);
let minutes = Math.floor((duration / (1000 * 60)) % 60);
let hours = Math.floor((duration / (1000 * 60 * 60)) % 24);
hours = hours.toString().padStart(2, '0');
minutes = minutes.toString().padStart(2, '0');
seconds = seconds.toString().padStart(2, '0');
milliseconds = milliseconds.toString().padStart(3, '0');
return hours + ":" + minutes + ":" + seconds + "." + milliseconds;
}
}
const out = document.querySelector("#out");
const list = document.querySelector("#list");
const myStopWatch = new StopWatch();
myStopWatch
.on('update', function(data) {
out.textContent = data.time;
})
.on('mark', function(data) {
var li = document.createElement("li");
li.textContent = data.marks.pop();
list.appendChild(li);
}).on('reset', function () {
list.innerHTML = '';
});
const wrapper = document.querySelector("#actions");
wrapper.addEventListener("click", function (evt) {
const action = evt.target.dataset.action;
myStopWatch[action]();
});
<div id="out"></div>
<div id="actions">
<button data-action="start">Start</button>
<button data-action="stop">Stop</button>
<button data-action="mark">Mark Time</button>
<button data-action="reset">Reset</button>
</div>
<ol id="list"></ol>