我正在尝试实现一个计时器,用户可以在其中选择小时数和分钟数,然后当用户按下按钮时就可以实时倒数。我正在使用setInterval()函数来计算剩余时间并更新页面。 SetInterval()每秒应运行一次,但是计时器值仅更新一次(按下按钮时)。
这很奇怪,因为我已经测试了其他功能,这些功能可以在相同范围内写入页面的相同区域,并且这些功能会重复更新(例如不断获取当前日期并输出它;我可以看到秒和分钟)列打勾)。这使我相信问题出在代码退出countDown()函数时如何查看小时/分钟/秒变量,但我似乎无法找出任何原因。
这是我的代码。作为参考,我只是尝试在单个HTMl文件中执行此操作,而无需网络连接。
HTML:
<body>
<!--section for controlling & displaying round timer-->
<div name="timeLeft" id="D3">
Round Timer<br>
Hours:
<select name="hours" id="S1">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
</select>
Minutes:
<select name="minutes" id="S2">
<option value="0">0</option>
<option value="5">5</option>
<option value="10">10</option>
<option value="15">15</option>
<option value="20">20</option>
<option value="25">25</option>
<option value="30">30</option>
<option value="35">35</option>
<option value="40">40</option>
<option value="45">45</option>
<option value="50">50</option>
<option value="55">55</option>
</select>
<br>
<input type="button" name="countDownStart" id="B2" onclick="countDown()" value="Start Countdown">
<br>
Your round will end in <span name="timerDisplay" id="span1">00:00:00</span>
</div>
</body>
Javascript:
<script type="application/javascript">
var timerInterval = null;
var hours;
var minutes;
var seconds;
function countDown() {
timerInterval = setInterval(function() {
//get user's inputs for hours and minutes
hours = parseInt(document.getElementById("S1").value);
minutes = parseInt(document.getElementById("S2").value);
seconds = 0; //the user cannot select the # of seconds
//get current date
var currentDate = new Date();
//get the countDownDate, which is the current date plus the user's values
var countDownDate = new Date();
countDownDate.setHours(currentDate.getHours() + hours);
countDownDate.setMinutes(currentDate.getMinutes() + minutes);
//find the difference between the two dates in hours, minutes, seconds
var dateDifference = new Date();
dateDifference = countDownDate - currentDate;
//convert the values in dateDifference to milliseconds
//math.floor() here returns the largest integer less than or equal to the appropriate
//measurement of time, in milliseconds
hours = Math.floor((dateDifference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
minutes = Math.floor((dateDifference % (1000 * 60 * 60)) / (1000 * 60));
seconds = Math.floor((dateDifference % (1000 * 60)) / 1000);
//update the countdown timer with these new values every 1000 milliseconds
document.getElementById("span1").innerHTML = hours + ":" + minutes + ":" + seconds;
}, 1000);
</script>
答案 0 :(得分:0)
您的间隔运行良好,但是问题在于一次性初始化代码与更新代码结合在一起了。您需要在setInterval
回调的每个刻度上重置计时器,并且计时器始终显示为过期。一种解决方法是将一次性初始化代码与重复更新代码分开,从而为代码提供固定的将来使用时间。
我还建议以是否已存在间隔为条件来启动计时器,否则,如果用户按[Start Countdown]按钮,则会创建一系列间隔并同时运行。
我将变量移出了全局范围,但您可能还考虑使用闭包来维护区间状态,事件侦听器,并提供比"S1"
,"S2"
,{ {1}}等。
"B2"
var timerInterval = null;
function countDown() {
if (!timerInterval) {
var hours = parseInt(document.getElementById("S1").value);
var minutes = parseInt(document.getElementById("S2").value);
var countDownDate = new Date();
countDownDate.setHours(countDownDate.getHours() + hours);
countDownDate.setMinutes(countDownDate.getMinutes() + minutes);
timerInterval = setInterval(function () {
var dateDifference = countDownDate - new Date();
var hours = Math.floor((dateDifference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = Math.floor((dateDifference % (1000 * 60 * 60)) / (1000 * 60));
var seconds = Math.floor((dateDifference % (1000 * 60)) / 1000);
document.getElementById("span1").innerHTML = `${hours}:${minutes}:${seconds}`;
}, 1000);
}
}
答案 1 :(得分:0)
这是一个简单的修复程序。我认为您不需要所有日期逻辑。其他所有内容都可以保持不变。这将基于总时间中的秒存储当前时间。每个循环将其推断为一个小时/分钟/秒,然后增加自您开始以来经过的秒数。这将大大简化该过程,并且可能更具可读性。试试看:
var startedTimeStamp;
var timerInterval = null;
var secondsAccrued = 0;
var initialTimer = 0;
function countDown() {
//Let's set this once and be done with it. It is the total number of seconds that the user has selected for their count down.
initialTimer = (parseInt(document.getElementById("S1").value) * 3600) + (parseInt(document.getElementById("S2").value) * 60);
startedTimeStamp = new Date();
timerInterval = setInterval(function() {
//How many seconds are left in the countdown?
secondsAccrued = (new Date() - startedTimeStamp) / 1000;
var currentTime = initialTimer - secondsAccrued;
//How many hours/minutes/seconds? Convert these to seconds, and make sure to subtract the hours from the total, and then minutes from the total, before determining the seconds the user should see.
var hours = Math.floor(currentTime / 3600);
var minutes = Math.floor((currentTime - (hours * 3600)) / 60);
var seconds = Math.round(Math.abs(currentTime - (currentTime - (hours * 3600)) - (currentTime -(minutes * 60))));
document.getElementById("span1").innerHTML = hours + ":" + minutes + ":" + seconds;
}, 1000);
}
编辑:已编辑,可以再次使用DateTimes来确保每个注释的准确性。经过测试并可以正常工作。