简体   繁体   中英

Why is my date object returning back NaN values?

Here is my JS fiddle:

https://jsfiddle.net/apasric4/xkzwqr1m/1/

My program is supposed to start a countdown timer that calculates the time remaining in days, hours, seconds, etc from today till the the date that the user picks in the input field.

While the program updates the HTML with the correct time remaining, the problem starts when I try to update countdown timer every second. It returns back NaN values for some reason. Why is that??

Here's my 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
  }
}

When update goes from event - all is fine

But later you use timeInterval=setInterval(updateHTML, 1000) - and updateHTML gets executed without parameter . Use real date instead and it will work

Working example:

 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>

So your code works fine but your problem is with your endTime . In your setInterval , you are calling updateHTML without the parameter endTime so that causes an error as it doesn't have a reference for the param.

You can either simply update your updateCounter function to accept this as a parameter and pass it to your setInterval function:

function updateCounter (endTime) {
  if (timeStop) {
    timeInterval=setInterval(() => updateHTML(endTime), 1000)
  } else {
    clearInterval(timeInterval)
  }
}

and then call updateCounter with the endTime at the bottom of your updateHtml function.

Or, remove endTime as a parameter from updateHtml and make it a global variable:

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...

try this....

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
  }
}

Just add preventDefault() in function updateCounter() in your code. Hope it will work. I tried and it worked successfully.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM