/**
* @param {date} expires - 过期时间
* @param {date} sysTime - 系统时间,默认为客户端当前时间
* @param {number} interval - 倒计时间隔,默认为1秒
* @param {boolean} renturnDay - 返回时间是否包含天,默认false
* @param {function} callback - 回调函数,回调数据格式如:{ d: 1, h: 1, m: 22, s: 58, ms: 4 },没回调数据时表示已结束。
* @return {function} 用于暂停倒计时
*/
function startCountDown({ expires, sysTime = new Date(), interval = 1000, renturnDay = false, callback } = {}) {
if (!expires) return;
let timer = null;
// 剩余时间
let remainTime = new Date(expires).getTime() - new Date(sysTime).getTime();
if (remainTime <= 0) {
// 没回调入参说明已结束
callback && callback();
return;
}
let startTime = Date.now();
function countDown() {
let endTime = Date.now();
// 这里不能直接用remainTime - interval,不然会有误差
// 因为定时器不一定会完全按照interval间隔去执行,很多时候执行时,间隔都已经大于interval值了。
remainTime = remainTime - (endTime - startTime);
startTime = endTime;
if (remainTime <= 0) {
// 没回调入参说明已结束
callback && callback();
} else {
callback && callback(getTimeData(remainTime, renturnDay));
timer = setTimeout(countDown, interval);
}
}
callback && callback(getTimeData(remainTime, renturnDay));
timer = setTimeout(countDown, interval);
return () => {
timer && clearTimeout(timer);
timer = null;
}
}
function getTimeData(time = 0, renturnDay = false) {
let d, h;
if (renturnDay) {
d = Math.floor((time / 1000 / 60 / 60 / 24));
h = Math.floor((time / 1000 / 60 / 60 % 24));
} else {
h = Math.floor((time / 1000 / 60 / 60));
}
const m = Math.floor((time / 1000 / 60 % 60));
const s = Math.floor((time / 1000 % 60));
let ms = Math.floor(time % 1000);
ms = parseInt(ms / 100);
return { d, h, m, s, ms };
}
startCountDown({
interval: 100,
expires: new Date('2021-09-04 20:50'),
renturnDay: true,
callback: (data) => {
if (data) {
console.log(data.d, '天', data.h, '小时', data.m, '分', data.s, '秒', data.ms);
} else {
console.log('倒计时结束');
}
}
});
11-21
659
04-02
7732
10-06
1536
09-02
264