倒计时项目中奇怪的 setInterval 问题
Posted
技术标签:
【中文标题】倒计时项目中奇怪的 setInterval 问题【英文标题】:Weird setInterval issue in a countdown project 【发布时间】:2022-01-23 04:16:21 【问题描述】:我一边看教程一边写项目(比如,听我必须做的事情,然后自己做,看看我是否能成功)。这是代码:
const months = [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
];
const weekdays = [
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
];
const deadline = document.querySelector(".deadline");
const giveaway = document.querySelector(".giveaway");
const h4 = document.querySelectorAll(".deadline-format h4");
let futureDate = new Date(2022, 4, 17, 11, 30, 0);
const yearTime = futureDate.getFullYear();
const monthTime = futureDate.getMonth();
const dayTime = futureDate.getDay();
const dateTime = futureDate.getDate();
const hourTime = futureDate.getHours();
const minutesTime = futureDate.getMinutes();
giveaway.innerhtml = ` Giveaway ends on $weekdays[dayTime], $dateTime $months[monthTime] $yearTime, $hourTime:$minutesTimeam`;
const futureTime = futureDate.getTime();
const currentTime = new Date().getTime();
let getRemainingTime = () =>
const timeLeft = futureTime - currentTime;
const oneDay = 24 * 60 * 60 * 1000;
const oneHour = 60 * 60 * 1000;
const oneMinute = 60 * 1000;
const oneSecond = 1000;
let days = Math.floor(timeLeft / oneDay);
let hours = Math.floor((timeLeft % oneDay) / oneHour);
let mins = Math.floor(((timeLeft % oneDay) % oneHour) / oneMinute);
let secs = Math.floor(
(((timeLeft % oneDay) % oneHour) % oneMinute) / oneSecond
);
const values = [days, hours, mins, secs];
let zeroBefore = (item) =>
if (item < 10)
return (item = `0$item`);
else
return item;
;
h4.forEach((item, index) =>
item.innerHTML = zeroBefore(values[index]);
);
;
// countdown
let countdown = setInterval(getRemainingTime, 1000);
//set initial values
getRemainingTime();
问题出现在函数开始之前:
const futureTime = futureDate.getTime();
const currentTime = currentDate.getTime();
let getRemainingTime = () =>
const timeLeft = futureTime - currentTime;
const oneDay = 24 * 60 * 60 * 1000;
const oneHour = 60 * 60 * 1000;
const oneMinute = 60 * 1000;
const oneSecond = 1000;
let days = Math.floor(timeLeft / oneDay);
let hours = Math.floor((timeLeft % oneDay) / oneHour);
let mins = Math.floor(((timeLeft % oneDay) % oneHour) / oneMinute);
let secs = Math.floor(
(((timeLeft % oneDay) % oneHour) % oneMinute) / oneSecond
);
const values = [days, hours, mins, secs];
let zeroBefore = (item) =>
if (item < 10)
return (item = `0$item`);
else
return item;
;
h4.forEach((item, index) =>
item.innerHTML = zeroBefore(values[index]);
);
基本上,问题在于变量“currentTime”超出了函数范围,因此实时页面由于某种原因不会每秒更新一次。相反,如果我将“currentTime”放入函数中,它会突然起作用。为什么会这样?为什么我需要将变量“currentTime”放入函数中,而我不需要将变量“futureTime”放入函数中,它在我的函数中与“currentTime”的用法相同? 谢谢,如果我做错了什么对不起,这是我在这个网站上的第一篇文章!
【问题讨论】:
【参考方案1】:我不确定我是否会形容你所看到的很奇怪。这对我来说似乎完全可以解释。
如果你在你的函数之外声明currentTime
,即
const currentTime = new Date().getTime();
let getRemainingTime = () =>
const timeLeft = futureTime - currentTime;
...
;
然后在您的脚本加载时评估一次currentTime
。每次调用 getRemainingTime()
时,currentTime
的值都相同,因此您的代码似乎没有做任何事情,因为它每次运行时都会计算出相同的剩余时间。
另一方面,如果您在函数中声明 currentTime
,即
let getRemainingTime = () =>
const currentTime = new Date().getTime();
const timeLeft = futureTime - currentTime;
...
;
然后每次调用您的函数时都会评估currentTime
。每次调用它可能会有不同的值,因此它会在每种情况下计算不同的剩余时间。
您无需对futureTime
执行相同操作,因为该值不会改变。
请注意,在您的第二个代码块中,您引用了一个名为 currentDate
的变量,您没有在任何地方定义它。您的第一个代码块中的相应行使用 new Date()
代替,我假设这就是您的意思。
【讨论】:
哦,好吧,这就是问题所在!我认为只需使用 setInterval 再次重新加载代码就足以一次又一次地返回当前时间,但似乎我错了。非常感谢您的帮助!是的,我把贴在帖子上的第二个代码搞砸了,抱歉,我在帖子中做了一些更改。以上是关于倒计时项目中奇怪的 setInterval 问题的主要内容,如果未能解决你的问题,请参考以下文章
Chrome开发者工具中奇怪的console.log行为[重复]