计时器是日常生活中最常见的功能之一也是学习定时器 API 的经典案例。本文通过微信小程序实现一个 60 秒倒计时器首页先显示空白页面2 秒后自动展示计时界面支持开始、停止、重新计时三种操作并完成 在时间显示界面上增加形容时间如流水的背景文字 的功能扩展。1 案例背景小程序运行后首页显示空白界面过 2 秒以后显示计时界面。计时界面包含计时数字和三个计时按钮开始计时、停止计时、重新计时。计时按钮的初始值为 60。这个案例用来练习 setTimeout、setInterval、clearInterval 三个定时器 API 的配合使用。2 案例目标与实现效果本案例一共有六个实现效果效果 1刚开始展示空白页面2 秒钟以后展示计时界面紫色边框区域内显示 计时器函数的应用、数字 60下方显示三个按钮 效果 2点击 开始计时 按钮开始倒计时 效果 3点击 停止计时 按钮停止计时 效果 4再点击 开始计时 按钮继续计时接着当前的数字倒计时 效果 5计时完成数字倒计时到 0此时点击 开始计时 或 停止计时数字仍然是 0 效果 6点击 重新计时 按钮从 60 开始重新倒计时。3 技术要点3.1 setTimeout延迟执行一次setTimeout (function callback, number delay) 用于设定一个定时器在定时到期以后执行注册的回调函数且只执行一次回调函数。本案例用它实现 过 2 秒以后显示计时界面。3.2 setInterval周期执行setInterval (function callback, number delay) 按照指定的周期以毫秒计反复执行注册的回调函数。本案例用 1000ms 的周期执行回调实现每秒减 1 的倒计时。3.3 clearInterval取消定时器clearInterval (number intervalID) 用于取消由 setInterval 设置的定时器参数是要取消的定时器的 ID。点击 停止计时 时调用它停止倒计时。3.4 生命周期函数与数据绑定onLoad 在页面加载时触发一次适合在这里启动 2 秒的延迟定时器this.setData () 修改 data 中的值并驱动界面更新。4 实现步骤4.1 新建项目在微信开发者工具中新建一个不使用云服务、不使用模板的小程序项目。4.2 修改 app.json使用 webview 渲染引擎将 renderer 设置为 webview。4.3 修改 index.wxml计时界面主要由计时显示界面和三个按钮组成。外层用一个紫色边框区域timer-panel把提示文字和计时数字包起来计时数字用 {{number}} 绑定三个按钮用 view 实现并分别绑定点击响应函数 startCountdown、stopCountdown、restartCountdown计时界面整体用 wx:if{{showTimer}} 控制显示。4.4 修改 index.wxss编写紫色边框区域、计时数字显示界面和三个按钮的样式。数字显示界面是蓝色圆角矩形、内部显示黄色数字三个按钮为绿色圆角按钮固定宽度、带间隙地横向排列page 和 .scrollarea 的样式是创建项目时自动生成的其它都是新增的样式。4.5 修改 app.wxss设置页面背景等全局样式。4.6 修改 index.jsonLoad 中通过 setTimeout 延迟 2 秒把 showTimer 置为 truestartCountdown 用 setInterval 每秒让 number 减 1stopCountdown 用 clearInterval 停止restartCountdown 先停止、再把数字重置为 60、然后重新开始倒计时。5 功能扩展作业要求在时间显示界面上增加形容时间如流水的背景文字。实现方式在数字显示界面上加入文字 逝者如斯夫 不舍昼夜使用 CSS 伪元素 .time::before并采用绝对定位position: absolute;同时将宿主元素.time上加上相对定位position: relative;。这样背景文字以 .time 盒子为定位参考白色文字叠加在蓝色圆角框内部上方、计时数字的上方与计时界面融为一体。6 关键代码6.1 index.wxml 关键片段view classmain wx:if{{showTimer}} view classtimer-panel view classtip计时器函数的应用/view view classtime{{number}}/view /view view classbtn-group view classtimer-btn bind:tapstartCountdown开始计时/view view classtimer-btn bind:tapstopCountdown停止计时/view view classtimer-btn bind:taprestartCountdown重新计时/view /view /view6.2 index.wxss 关键片段紫色边框 功能扩展 按钮.timer-panel { width: 560rpx; border: 4rpx solid #9b59f6; /* 紫色边框区域 */ border-radius: 20rpx; display: flex; flex-direction: column; align-items: center; } .time { position: relative; /* 宿主元素加上相对定位 */ ... } .time::before { content: 逝者如斯夫 不舍昼夜; position: absolute; /* 伪元素绝对定位 */ top: 18rpx; /* 白色文字叠加在蓝色圆角框内部上方 */ left: 50%; transform: translateX(-50%); color: #ffffff; ... } .btn-group { display: flex; flex-direction: row; align-items: center; margin-top: 50rpx; } .timer-btn { width: 170rpx; /* 按钮固定宽度保证不超出屏幕 */ height: 76rpx; line-height: 76rpx; text-align: center; font-size: 28rpx; color: #ffffff; background-color: #07c160; border-radius: 12rpx; margin: 0 16rpx; /* 按钮之间的缝隙 */ }6.3 index.js 关键片段onLoad() { // 过 2 秒以后显示计时界面setTimeout 只执行一次 setTimeout(() { this.setData({ showTimer: true }) }, 2000) } // 开始计时每秒减 1已到 0 则保持 0 startCountdown() { if (this.timer) return this.timer setInterval(() { if (this.data.number 0) { clearInterval(this.timer) this.timer null return } this.setData({ number: this.data.number - 1 }) }, 1000) } // 停止计时取消定时器 stopCountdown() { if (this.timer) { clearInterval(this.timer) this.timer null } } // 重新计时从 60 开始重新倒计时 restartCountdown() { this.stopCountdown() this.setData({ number: 60 }) this.startCountdown() }7 踩坑与注意事项重复点击 开始计时 会叠加多个定时器导致倒计时加速。解决方式在创建定时器前先判断是否已有定时器在运行已有则直接返回停止时把定时器置空。倒计时到 0 后要清除定时器并置空同时不再让数字减到负数这样再点 开始 或 停止数字仍然保持 0。重新计时 的语义是重置为 60 并重新开始倒计时因此要先停止旧定时器再重置数字最后重新开始。定时器要在页面卸载onUnload时清理避免页面关闭后定时器仍在执行。伪元素 ::before 要配合绝对定位使用且宿主元素必须设置相对定位否则定位参考不正确。微信 button 组件自带默认边框和宽高样式容易把按钮撑宽、超出屏幕建议用 view 配合固定宽度实现按钮并保留清晰间隙。8 总结本案例利用 setTimeout 延迟 2 秒显示计时界面、setInterval 每秒减 1 实现倒计时、clearInterval 停止计时并处理好 到 0 保持 0 和 重新计时 等边界逻辑界面采用紫色边框区域布局功能扩展通过 CSS 伪元素 .time::before 配合绝对定位在时间显示界面增加了 逝者如斯夫 不舍昼夜 的白色背景文字。掌握定时器 API 与边界状态处理可以进一步实现秒表、番茄钟、倒计时抢购等实用功能。9 参考资料[1] 微信开放文档・定时器setTimeout—— number setTimeout(function callback, number delay, any rest) | 微信开放文档[2] 微信开放文档・定时器setInterval—— number setInterval(function callback, number delay, any rest) | 微信开放文档[3] 微信开放文档・定时器clearInterval—— clearInterval(number intervalID) | 微信开放文档[4] MDN・CSS ::before 伪元素 ——https://developer.mozilla.org/zh-CN/docs/Web/CSS/::before