我正在尝试在2个日期之间创建倒数计时器,但是时间过了一会儿就消失了。
我的PHP后端返回当前时间与将来的X时间之间的时差,例如当前时间和提前2小时。这种差异以以下格式.countdown
传递给03:20:15
类的$(".countdown").each(function() {
var $e = $(this);
var interval = setInterval(function() {
var timer2 = $e.html();
var timer = timer2.split(':');
var hours = parseInt(timer[0], 10);
var minutes = parseInt(timer[1], 10);
var seconds = parseInt(timer[2], 10);
--seconds;
minutes = (seconds < 0) ? --minutes : minutes;
hours = (minutes < 0) ? --hours : hours;
if(hours < 0) {
clearInterval(interval);
window.location.reload();
} else {
seconds = (seconds < 0) ? 59 : seconds;
seconds = (seconds < 10) ? '0' + seconds : seconds;
minutes = (minutes < 0) ? 59 : minutes;
minutes = (minutes < 10) ? '0' + minutes : minutes;
hours = (hours < 10) ? '0' + hours : hours;
$e.html(hours + ':' + minutes + ':' + seconds);
}
}, 1000);
});
类中的HTML前端,我使用javascript函数来计算差异。这是我的功能:
span.passive.match + ul:has(span.active.match)
代码按预期工作,但几分钟后(例如2-3分钟),如果刷新页面或在新窗口中打开页面,您将看到倒数计时器落后秒数/分钟。有人知道我在做什么错吗?
答案 0 :(得分:2)
您应该计算(new Date())与目标日期之间的差。使用该差异并设置新HTML字符串的格式,而不是将其解析为小时,分钟,秒的值进行递减。
详细信息
setInterval api规范建议应预期由于CPU负载,其他任务等导致的延迟。 https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers
您的处理程序会以大约相等的间隔被调用,而您认为它们是正确的。第一次迭代时,实际时间可能与计划时间相差很小的时间(例如4毫秒)。但是,您将计数器更改了1000 ms。随着更多次迭代的进行,这种差异不断累积并变得明显。几分钟就足以使这种情况发生。
另一方面,如果您预先计算目标日期时间值,并使用当前时间和目标时间之间的差值,则您的代码对api不精确将不敏感。
$(".countdown").each(function () {
var $e = $(this);
const totalSeconds = (dt) => Math.floor(dt.valueOf() / 1000);
const f1 = (timer2) => {
var timer = timer2.split(':');
var tdt = new Date().setHours(
parseInt(timer[0]) + tdt.getHours(),
parseInt(timer[1]) + tdt.getMinutes(),
parseInt(timer[2]) + tdt.getSeconds());
return totalSeconds(tdt);
};
const targetTime = f1($e.html());
setInterval(function () {
var timeSpan = targetTime - totalSeconds(new Date());
if (timeSpan < 0) {
window.location.reload();
} else {
var seconds = timeSpan % 60;
var totalMinutes = Math.floor(timeSpan / 60);
var minutes = totalMinutes % 60;
var hours = Math.floor(totalMinutes / 60);
$e.html(hours + ':' + minutes + ':' + seconds);;
}
}, 1000);
});