我的程序应该启动一个倒计时器,计算从今天到用户在输入字段中选择的日期的剩余时间(以天、小时、秒等为单位)。
虽然程序用正确的剩余时间更新 HTML,但当我尝试每秒更新倒计时器时,问题就开始了。由于某种原因它返回 NaN 值。 这是为什么??
这是我的JS:
const input = document.querySelector('input')
let timeInterval;
let timeStop;
input.addEventListener('change', (e) => {
e.preventDefault()
timeStop = true;
endTime = Date.parse(e.target.value)
updateHTML(endTime)
})
function updateHTML(endTime) {
let time = calculateTimeDiff(endTime)
if (time.total <= 0) {
timeStop = false;
}
for (let pro in time) {
let el = document.querySelector(`.${pro}`)
if (el) {
el.innerHTML = time[pro];
}
}
updateCounter();
}
function updateCounter () {
if (timeStop) {
timeInterval = setInterval(updateHTML, 1000);
} else {
clearInterval(timeInterval);
}
}
//returning time remaining till date in object form
function calculateTimeDiff(endTime) {
let start = Date.now();
let end = endTime;
let t = (end-start);
let seconds = Math.floor((t / 1000) % 60);
let minutes = Math.floor((t / 1000 / 60) % 60);
let hours = Math.floor((t / (1000 * 60 * 60)) % 24);
let days = Math.floor(t / (1000 * 60 * 60 * 24));
return {
total: t,
days: days,
hours: hours,
minutes: minutes,
seconds: seconds
}
}
所以你的代码工作正常,但你的问题在于你的
endTime
。在您的 setInterval
中,您在不带参数 updateHTML
的情况下调用 endTime
,因此会导致错误,因为它没有参数的引用。
您可以简单地更新您的
updateCounter
函数以接受此参数并将其传递给您的 setInterval
函数:
function updateCounter (endTime) {
if (timeStop) {
timeInterval=setInterval(() => updateHTML(endTime), 1000)
} else {
clearInterval(timeInterval)
}
}
然后使用
updateCounter
函数底部的 endTime
调用 updateHtml
。
或者,从
endTime
中删除 updateHtml
作为参数,并将其设为全局变量:
const input=document.querySelector('input')
let timeInterval;
let timeStop;
let endTime;
input.addEventListener('change', (e)=> {
e.preventDefault()
timeStop=true;
endTime=Date.parse(e.target.value)
updateHTML()
})
function updateHTML () {
let time=calculateTimeDiff(endTime)
if (time.total<=0) {
timeStop=false
}
for (let pro in time) {
let el=document.querySelector(`.${pro}`)
if (el) {
el.innerHTML=time[pro]
}
}
updateCounter()
}
etc...
当更新从事件中消失时 - 一切都很好
但是稍后您使用
timeInterval=setInterval(updateHTML, 1000)
- 并且 updateHTML
在没有参数的情况下执行。使用真实日期来代替,它会起作用
工作示例:
const input = document.querySelector('input')
let timeInterval;
let timeStop;
let savedTime;
input.addEventListener('change', (e) => {
e.preventDefault()
timeStop = true;
endTime = Date.parse(e.target.value)
updateHTML(endTime)
})
function updateHTML(endTime) {
savedTime = endTime || savedTime;
let time = calculateTimeDiff(savedTime)
if (time.total <= 0) {
timeStop = false
}
for (let pro in time) {
let el = document.querySelector(`.${pro}`)
if (el) {
el.innerHTML = time[pro]
}
}
updateCounter()
}
function updateCounter() {
if (timeStop) {
timeInterval = setInterval(updateHTML, 1000)
} else {
clearInterval(timeInterval)
}
}
//returning time remaining till date in object form
function calculateTimeDiff(endTime) {
let start = Date.now()
let end = endTime
let t = (end - start)
let seconds = Math.floor((t / 1000) % 60);
let minutes = Math.floor((t / 1000 / 60) % 60);
let hours = Math.floor((t / (1000 * 60 * 60)) % 24);
let days = Math.floor(t / (1000 * 60 * 60 * 24));
return {
total: t,
days: days,
hours: hours,
minutes: minutes,
seconds: seconds
}
}
.time {
display: inline-block;
border-radius: 25%;
}
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="styles.css">
</head>
<body>
<input type="date" name="endDate">
<div class="clock">
<div class="time"><span class="days">0</span> Days</div>
<div class="time"><span class="hours">0</span> Hours</div>
<div class="time"><span class="minutes">0</span> Minutes</div>
<div class="time"><span class="seconds">0</span> Seconds</div>
</div>
</body>
<script src="app.js"></script>
</html>
试试这个....
const input=document.querySelector('input')
let timeInterval;
let timeStop;
let endTime;
input.addEventListener('change', (e)=> {
e.preventDefault()
timeStop=true;
endTime=Date.parse(e.target.value)
updateHTML()
})
function updateHTML () {
let time=calculateTimeDiff()
if (time.total<=0) {
timeStop=false
}
for (let pro in time) {
let el=document.querySelector(`.${pro}`)
if (el) {
el.innerHTML=time[pro]
}
}
updateCounter()
}
function updateCounter () {
if (timeStop) {
timeInterval=setInterval(updateHTML(), 1000)
} else {
clearInterval(timeInterval)
}
}
//returning time remaining till date in object form
function calculateTimeDiff () {
let start=Date.now()
let end=endTime
let t=(end-start)
let seconds = Math.floor((t / 1000) % 60);
let minutes = Math.floor((t / 1000 / 60) % 60);
let hours = Math.floor((t / (1000 * 60 * 60)) % 24);
let days = Math.floor(t / (1000 * 60 * 60 * 24));
return {
total: t,
days: days,
hours: hours,
minutes: minutes,
seconds: seconds
}
}
只需在代码中的函数 updateCounter() 中添加 PreventDefault() 即可。 希望它能起作用。我尝试了一下,成功了。