นาฬิกา Javascript นับผ่าน 60 นาทีและวินาที
ฉันได้สร้างนาฬิกา Javascript เมื่อวินาทีและนาทีถึง 60 มันจะนับมากกว่า 60 และจะดำเนินต่อไป ...
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>
โดยทั่วไปนาฬิกาจะนับเวลาผ่านไป 60 นาทีเป็นนาทีและวินาทีฉันต้องการให้รีเซ็ตเป็น 0 แทนการกดปุ่ม 60 ฉันไม่มีเวลาทดสอบชั่วโมงแม้ว่าฉันแน่ใจว่าจะเลย 24 ไปแล้วก็ตาม
ใครช่วยอธิบายวิธีการนี้ได้บ้าง? ฉันมั่นใจว่ามันง่ายมาก แต่ฉันพยายามต่อสู้กับมันมานานเกินไปและเริ่มหงุดหงิด
คำตอบ
คุณสามารถใช้ตัวดำเนินการส่วนที่เหลือ ( %) เพื่อตัดกลับเป็น 0 เมื่อตัวเลขผ่าน 60
ตัวอย่างเช่น
59 % 60 === 5960 % 60 === 061 % 60 === 1
ดังนั้นรหัสของคุณจะมีลักษณะดังนี้:
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>
โปรดทราบว่าตัวจับเวลานี้อาจเลื่อนไปตามกาลเวลา สำหรับสาเหตุและวิธีแก้ปัญหานั้นโปรดดูวิธีสร้างตัวจับเวลาที่แม่นยำในจาวาสคริปต์
คุณไม่สามารถวางใจได้ว่า setTimeout หรือ setInterval จะดำเนินการใน X มิลลิวินาที ดูวิดีโอต่อไปนี้เกี่ยวกับเหตุการณ์ที่เกิดขึ้นเพื่อทำความเข้าใจว่าเหตุใด เป็นสิ่งที่คุณควรรู้เมื่อเขียนโปรแกรมจาวาสคริปต์
สิ่งที่คุณแทนต้องทำคือการปรับปรุงองค์ประกอบของการส่งออกทุกครั้ง repaints หน้าจอที่คุณสามารถทำได้ด้วยrequestAnimationFrame คุณต้องจัดเก็บเมื่อนาฬิกาเริ่มต้นซึ่งสามารถทำได้ในหน่วยมิลลิวินาทีจากนั้นคำนวณจากความแตกต่างระหว่างเวลาเริ่มต้นและเวลาปัจจุบัน (ด้วยDate.now()) เมื่อหน้าต่างกำลังจะทาสีใหม่ requestAnimationFrameรับการเรียกกลับเป็นพารามิเตอร์ซึ่งควรเป็นวิธีการที่อัปเดตองค์ประกอบเอาต์พุตของคุณ
แก้ไข: ฉันเร่งตัวจับเวลาเพื่อแสดงกรณีการรีเซ็ตนาทีและวินาที
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>
คุณสามารถใช้String.padStartเพื่อแทรก0สัญลักษณ์สำหรับค่าดิจิทัล
และแทนที่จะเรียกฟังก์ชั่นภายในsetTimeoutสำหรับคุณสามารถใช้recursive เพื่อล้างจัดการเวลาที่คุณสามารถใช้setIntervalclearInterval
และพระรามที่สองของการsetIntervalเป็นมูลค่าเพื่อที่จะนับเวลาจากวินาทีนั้นมันจะดีไปยังชุดmiliseconds1000 - 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>
นี่เป็นวิธีที่ดีเกินไปสำหรับสิ่งที่คุณกำลังทำ แต่มีวิธีที่ดีในการจัดรูปแบบสตริงเวลา นอกจากนี้ยังแสดงวิธีใช้ Date.now () เพื่อติดตามความแตกต่างของเวลา
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>