js实现计时器效果
使用 setTimeout 实现单次计时器
通过 setTimeout 可以在指定延迟后执行一次回调函数。适合单次延迟执行的场景。
setTimeout(() => {
console.log('计时结束');
}, 1000); // 1000毫秒后执行
使用 setInterval 实现循环计时器
通过 setInterval 可以按照固定时间间隔重复执行回调函数,直到被清除。
let counter = 0;
const intervalId = setInterval(() => {
counter++;
console.log(`已过去 ${counter} 秒`);
if (counter >= 5) {
clearInterval(intervalId); // 停止计时器
}
}, 1000); // 每秒执行一次
使用 requestAnimationFrame 实现动画计时器
requestAnimationFrame 是浏览器提供的专门用于动画的高性能计时API,会在每次重绘前执行回调。
let startTime = null;
function animate(timestamp) {
if (!startTime) startTime = timestamp;
const elapsed = timestamp - startTime;
console.log(`已运行 ${elapsed.toFixed(2)} 毫秒`);
if (elapsed < 2000) { // 运行2秒
requestAnimationFrame(animate);
}
}
requestAnimationFrame(animate);
实现可暂停的计时器
结合 Date 对象和变量控制,可以创建更灵活的计时器。
let startTime, elapsedTime = 0, timerId;
let isRunning = false;
function startTimer() {
if (isRunning) return;
isRunning = true;
startTime = Date.now() - elapsedTime;
timerId = setInterval(updateTimer, 10);
}
function pauseTimer() {
if (!isRunning) return;
isRunning = false;
clearInterval(timerId);
}
function resetTimer() {
isRunning = false;
clearInterval(timerId);
elapsedTime = 0;
document.getElementById('display').textContent = '00:00:00';
}
function updateTimer() {
const now = Date.now();
elapsedTime = now - startTime;
displayTime(elapsedTime);
}
function displayTime(time) {
const formatted = new Date(time).toISOString().substr(11, 8);
document.getElementById('display').textContent = formatted;
}
高性能计时器实现
对于需要高精度计时的场景,可以使用 performance.now() 替代 Date.now()。
let lastTime = performance.now();
function highPrecisionTimer() {
const now = performance.now();
const delta = now - lastTime;
lastTime = now;
console.log(`时间差: ${delta.toFixed(3)}ms`);
requestAnimationFrame(highPrecisionTimer);
}
requestAnimationFrame(highPrecisionTimer);
Web Worker 后台计时器
通过 Web Worker 可以在后台线程运行计时器,避免主线程阻塞。
worker.js:
let intervalId;
self.onmessage = function(e) {
if (e.data === 'start') {
let counter = 0;
intervalId = setInterval(() => {
counter++;
self.postMessage(counter);
}, 1000);
} else if (e.data === 'stop') {
clearInterval(intervalId);
}
};
主线程:
const worker = new Worker('worker.js');
worker.onmessage = function(e) {
console.log(`Worker 计时: ${e.data}秒`);
};
worker.postMessage('start');
// 停止计时
// worker.postMessage('stop');





