实战:秒杀倒计时。用 setInterval 每秒减一秒,算时分秒。
核心三步:
① 算差值——结束时间 - 当前时间 = 剩余毫秒
② 转时分秒——毫秒 / 1000 / 60 取整
③ 每秒更新——setInterval 每秒刷新
坑:Date 相减得毫秒、要补零(09:05:03)、到 0 要 clearInterval。
如果写成 count--,浏览器切到后台会暂停定时器,回来时数字就"慢"了。正确做法:记录结束时间戳,每秒用"结束时间 − 当前时间"现算剩余——后台回来也能立刻算对。
// 1. 先定好结束时刻:现在往后 2 小时(用毫秒时间戳算)
let endTime = Date.now() + 2 * 60 * 60 * 1000;
// 2. 每秒现算一次还剩多少秒(结束时刻 − 现在)
// Date.now() 是当前时间戳(毫秒)
let remain = Math.floor((endTime - Date.now()) / 1000);
// 3. 减到 0 就停
if (remain <= 0) {
// 把闹钟关了
clearInterval(timer);
// 页面上显示"活动已结束"
}
Date.now() 返回毫秒时间戳;Math.floor 向下取整(比如剩 99.7 秒显示 99 秒)。
// 一天有 86400 秒:先整除出"凑满了几天"
function formatTime(seconds) {
// % 是取余数:去掉整天后还剩多少秒,再除 3600 得小时
let day = Math.floor(seconds / 86400);
// 再去掉整天和整小时,剩下的除 60 得分钟
let hour = Math.floor(seconds % 86400 / 3600);
// 最后剩下的零头就是秒
let minute = Math.floor(seconds % 3600 / 60);
let sec = seconds % 60;
return day + "天" + hour + "时" + minute + "分" + sec + "秒";
}
口诀:先整除大的(天)、再用 % 取余算小的(时→分→秒)。比如 90061 秒 = 1 天 1 时 1 分 1 秒。
// 把闹钟编号先放空着
let timer = null;
// 第 1 步:定好结束时刻 = 现在往后 2 分钟
function start() {
let endTime = Date.now() + 2 * 60 * 1000;
// 第 2 步:定个每秒响一次的循环闹钟
timer = setInterval(function () {
// 第 3 步:每秒现算还剩多少秒
let remain = Math.floor((endTime - Date.now()) / 1000);
// 第 4 步:减到 0 了,关闹钟 + 显示结束
if (remain <= 0) {
// 先关闹钟
clearInterval(timer);
show("活动已结束");
// 后面的就别跑了
return;
}
// 第 5 步:把秒数拆成天时分秒,显示到页面上
show(formatTime(remain));
}, 1000);
}
归零分支里先 clearInterval 再 return,避免负数继续显示。作业要求"封装 formatTime"就是这么来的。
| API | 作用 | 参数 | 返回值 | 代码示例 |
|---|---|---|---|---|
| Date.now() | 当前时间戳(毫秒数) | 无 | 数字 | let now = Date.now(); // 当前毫秒时间戳 |
| Math.floor(毫秒/1000) | 毫秒换成整秒 | 毫秒数 | 秒数 | let sec = Math.floor(ms / 1000); // 毫秒转整秒 |
| % 取余 / Math.floor | 总秒数拆成天、时、分、秒 | 数字 | 余数/商 | let m = Math.floor(sec / 60); let s = sec % 60; |
| setInterval(函数, 1000) | 每秒刷新一次显示 | 函数、1000 毫秒 | ID | let t = setInterval(function () { 刷新显示 }, 1000); |
| clearInterval(ID) | 倒计时归零就停 | 定时器 ID | 无 | clearInterval(t); // 归零就停 |