【发布时间】:2021-01-22 09:36:21
【问题描述】:
所以我用 JavaScript 和 HTML 为一个项目创建了一个秒表,它只是一个通用秒表,对于 start_timer() 函数,我使用 setTimeout() 函数来确定速度。 但是,当我在浏览器中运行文件时,它们的计数似乎太慢,因为秒数不同步。 这里有视频来说明时钟有多慢:https://drive.google.com/file/d/1mqB4w5ZX7YqW8C57HhgWtIC63eyfKaGe/view?usp=sharing
我觉得这是一个非常愚蠢的问题,但非常感谢;)我想知道我是否需要使用网络工作者或其他东西(这是我的第一个完整的 javascript 项目,所以我对某些东西很陌生) 代码如下
var isTiming = false; //as mentioned in the Design, this is to determine whether the stopwatch IS counting or IS NOT
var speed = 10; //10 milliseconds count allowing for hundredths of a millisecond for better accuracy
var binaryTrue = 0; //checks to see if the stopwatch is paused
function start_stopwatch() { //function to start the counting
if (isTiming == true) {
var stopwatch = document.getElementById("TimeTable").innerHTML; //set the stopwatch to the digital clock in the HTML
//use of an array to display elapsed time in the format hh:mm:ss:lll
//each chronological place value is at a different spot in the array from left to right (numeric values)
var arr = stopwatch.split(":");
/*splits the array by separating each value (seconds, minutes, etc.) everytime there is a ":"
when a button is pressed */
var hr = arr[0]; //first position :hr: at the first space of the array
var min = arr[1]; //seccond position :mm at the second space of the array
var sec = arr[2]; //third position :ss at the third space of the array
var millisec = arr[3]; //fourth position :lll at the fourth space of the array
//Counting up in normal digital clock format, executes every 10 milliseconds which allows for hundredths of a second
//returns next value after 10 milliseconds are up
millisec++;
if (millisec < 10) {
millisec = "0" + millisec;
}
if (millisec / 100 === 1) {
millisec = 0;
millisec = "0" + millisec;
if (sec / 59 === 1) {
sec = 0;
sec = "0" + sec; //added in after the place value displayed as "0" and not "00"
if (min / 59 === 1) {
hr++;
min = 0;
min = "0" + min; //added in after the place value displayed as "0" and not "00"
sec = 0;
sec = "0" + sec; //added in after the place value displayed as "0" and not "00"
} else {
min++;
if (min < 10) {
min = "0" + min;
}
}
} else {
sec++;
if (sec < 10) {
if (sec < 1) {
sec = "0" + "0" + sec;
} //added in after it was displayed as "0" not "00"//
else {
sec = "0" + sec;
}
} else {
if (sec < 1) {
sec = "0" + sec;
}
}
}
}
//update the HTML digital time
document.getElementById("TimeTable").innerHTML = hr + ":" + min + ":" + sec + ":" + millisec; //modify the array to the updated time
setTimeout(start_stopwatch, (speed /* * ((6/7)/1.072)*/ )); //THIS TENDS TO BE OUT OF SYNC AS IT IS SLOWER THAN A NORMAL CLOCK. SO * ((6/7)/1.072) TO IMPROVE SPEED.
document.getElementById("control").innerHTML = "Pause";
}
}
//function to allow the user to change the speed of counting as desired, and as many times as they like
//
function change_speed() {
speedInput = window.prompt("Enter speed, where '1' = 1 second or '2' counts twice as fast, or '0.5' counts slower.");
//Input validation/verification as the user should only input an actual number, whether a float or an integer.
//isNaN is a useful function here where NaN means "Not a Number"
if (isNaN(speedInput)) { //if the value that the user puts in to change the speed into isn't actually (only) a number
speedInput = window.prompt("Enter speed AS A NUMBER where '1' = 1 second or '2' counts twice as fast, or '0.5' counts slower. Numbers only.");
}
speedLength = speedInput.length; //defensive design in the form of input validation - minimum length
speedInputHolder = speedInput;
speedInput = 1 / speedInputHolder; //converts speed requested by the USER into counting length (e.g. 2x speed = 0.5 second length, which is 2x faster, so accessible user interface)
if (speedInput === null) { // "Cancel" button pressed
speed = speed;
} else {
if (speedLength > 0) {
speedInputInMilliseconds = (speedInput * 10); //not * 1000 as tenth-seconds are included too
speed = (speedInputInMilliseconds /** ((60/7)/1.072)*/ ); //need to make sure the 4.275 method still syncs*/
}
}
if (speedInputHolder == 1) {
var indicateSpeed = document.getElementById("speedIndicator").innerHTML = "Counting speed: " + "(" + (1 / speedInput) + "x speed" + ")";
var indicateInterval = document.getElementById("FractionalIndicator").innerHTML = "Counting frequency: " + speedInput + " second."
} else {
var indicateSpeed = document.getElementById("speedIndicator").innerHTML = "Counting speed: " + "(" + (1 / speedInput) + "x speed" + ")";
var indicateInterval = document.getElementById("FractionalIndicator").innerHTML = "Counting frequency: " + speedInput + " seconds."
}
}
function change_state() { //function to change from start to pause or pause to start
if (isTiming == false) {
isTiming = true;
binaryTrue = 1;
start_stopwatch();
var started = document.getElementById("control").innerHTML = "Pause";
console.log("Timer started.");
} else {
stop_stopwatch();
console.log("Timer stopped.");
}
}
function reset() {
if (binaryTrue == 1) {
var reset = document.getElementById("TimeTable").innerHTML = "00" + ":" + "00" + ":" + "00" + ":" + "00";
if (isTiming == false) {
var started = document.getElementById("control").innerHTML = "Start";
}
console.log("Timer reset.");
} else {
if (binaryTrue == 0) {
var reset = document.getElementById("TimeTable").innerHTML = "00" + ":" + "00" + ":" + "00" + ":" + "00";
if (isTiming == false) {
var started = document.getElementById("control").innerHTML = "Start/Pause";
console.log("Timer reset.");
}
}
}
}
//Pausing the stop watch, so STOPPING it from continuing counting
//Set the isTiming variable as FALSE which controls the start_timer function from continuing
function stop_stopwatch() {
isTiming = false;
document.getElementById("control").innerHTML = "Resume";
console.log("Timer stopped.");
}
//the same as stop_stopwatch but also RESETS the stopwatch
/* if isTiming is already FALSE and so the timer is paused
change button label into "Start/Pause"
otherwise make isTiming to be FALSE and reset the timer to 00:00:00:00
and reset the label to "start"
(leave the label as "Start/Pause" if the stopwatch isn't used at least once yet so that the user can still see the original instructions")*/
function stop_and_reset_stopwatch() {
if (binaryTrue == 0) { //if the timer hasn't been used at least once
if (isTiming == false) {
document.getElementById("control").innerHTML = "Start/Pause"; //the user won't have knowledge of the instructions yet
}
} else {
isTiming = false;
document.getElementById("TimeTable").innerHTML = "00" + ":" + "00" + ":" + "00" + ":" + "00";
if (binaryTrue == 0) { //if the stopwatch HASN'T been used yet at least once, meaning that binaryTrue is still 0
document.getElementById("control").innerHTML = "Start/Pause";
} else { //if the stopwatch HAS been used at least once, meaning that binaryTrue is 1
document.getElementById("control").innerHTML = "Start";
}
}
console.log("Timer stopped and reset.");
}
<link href="https://fonts.googleapis.com/css2?family=Dosis:wght@600&display=swap" rel="stylesheet">
<div class="Stopwatch">
<div class="SpeedIndicator">
<div class="IntervalIndicator">
<div class="CountTable">
<p><span id="TimeTable" style="color: #00ffbf; font-size: 200px;">00:00:00:00</span></p>
<div class="Controllers">
<button id="control" onclick="change_state();">Start/Pause </button>
<button id="reset" onclick="reset();">Reset </button>
<button id="stop" onclick="stop_and_reset_stopwatch();">Stop and Reset</button>
<button id="speed" onclick="change_speed();">Change speed</button>
<script type="text/javascript" src="timer.js"></script>
<p><br><span id="Label" style="color: #00ffbf; font-size: 100px; font-weight: bold; font-family: Arial, Helvetica, sans-serif">hr:min:sec:hundredth</span></br>
</p>
<heading id="speedIndicator" style="color: #00aba3; font-size: 20px; font-family: Arial">Stopwatch speed: 1 second (default) </heading>
<br>
<heading id="FractionalIndicator" style="color: #00aba3; font-size: 10px; font-family: Arial"></heading>
</br>
【问题讨论】:
-
坦率地说,我什至不会尝试遵循所有这些代码,但是……
setTimeout和setInterval根本不保证任何具体的时间安排,不。你不能指望你的代码精确地在毫秒内执行,因为浏览器可能有也可能没有很多其他的事情要做,并且只会尽最大努力执行你的代码。您需要在编写代码时牢记这种期望。 -
同样可靠的最小超时时间约为10ms。低的一切都不可信。
标签: javascript settimeout stopwatch