道阻且长,行而不辍,未来可期
知识点一:
new Date().getTime()
可以得到得到1970年01月1日0点零分以来的毫秒数。单位是毫秒
scala
new Date().getTime()/1000获取秒数
1分钟60秒,1小时60分钟
1hour:60*60=>单位是秒 60*60*1000=>单位是秒
1day:24*60*60=>单位是秒 24*60*60*1000=>单位是秒
知识点二、
为什么使用 requestAnimationFrame 来写定时器呢?
答:当页面离开或切换到其他标签页时,requestAnimationFrame 中的代码将不再执行。
详解:因为 requestAnimationFrame 方法依赖于浏览器的渲染循环,而在页面不可见或失去焦点时,浏览器会暂停渲染循环以减少资源消耗。 因此,使用 requestAnimationFrame 实现的动画或定时器,在页面不可见或失去焦点时会自动暂停,直到页面重新可见或获得焦点时才会继续执行。 这是浏览器的默认行为,无需额外处理。
如果你希望即使在页面不可见时仍然执行代码,可以考虑使用 setTimeout 或 setInterval 这样的定时器函数,它们在页面不可见时仍会继续执行。不过请注意,频繁的定时器操作可能会对性能产生负面影响,因此需要谨慎使用。
如果不用 requestAnimationFrame,也可以用别的方法实现-->离开页面时定时器停止,回到页面时定时器继续走动的效果
方法:可以利用 window 对象的 blur 和 focus 事件来监听页面失去焦点和获得焦点的状态。
requestAnimationFrame是什么?
答:requestAnimationFrame 是浏览器提供的一个用于执行动画效果的 API。
它接收一个回调函数作为参数,并在下一次浏览器重绘之前执行该回调函数。
浏览器通常以每秒60帧(即每秒60次重绘)的速度运行动画,因此 requestAnimationFrame 的回调函数约每16.6毫秒(1000ms / 60)调用一次。
使用 requestAnimationFrame 可以确保动画在最佳的性能下运行,因为它会在浏览器准备好绘制下一帧之前执行回调函数。
这样可以避免不必要的重绘和浪费的资源。
需要注意的是,requestAnimationFrame 返回一个标识符(或称为句柄),可以使用该标识符来取消动画帧请求,使用 cancelAnimationFrame 函数进行取消操作。
代码demo:
scala
const { days, hours, minutes, seconds } = useCountDown2(
new Date("2023-08-22T03:35:00.000Z").getTime()
);
scala
import { useState, useEffect } from "react";
const oneDay = 1000 * 60 * 60 * 24;
const oneHour = 1000 * 60 * 60;
const oneMinute = 1000 * 60;
const oneSecond = 1000;
let timer=null;
export function useCountDown2(endDate) {
const [days, setDay] = useState('00');
const [hours, setHour] = useState('00');
const [minutes, setMinute] = useState('00');
const [seconds, setSecond] = useState('00');
const [endTime]=useState(endDate);
useEffect(() => {
const setLeftTime = () => {
//requestAnimationFrame 的单位是毫秒(ms)
const nowTime=Math.ceil(new Date().getTime());
const diff = endTime - nowTime;
let msec = diff;
const d = Math.floor(msec / oneDay);
msec -= d * oneDay;
const hh = Math.floor(msec / oneHour);
msec -= hh * oneHour;
const mm = Math.floor(msec / oneMinute);
msec -= mm * oneMinute;
const ss = Math.floor(msec / oneSecond);
msec -= ss * oneSecond;
setDay(`${d}`.replace(/^\d$/, '0$&'));
setHour(`${hh}`.replace(/^\d$/, '0$&'));
setMinute(`${mm}`.replace(/^\d$/, '0$&'));
setSecond(`${ss}`.replace(/^\d$/, '0$&'));
timer= requestAnimationFrame(setLeftTime);
if (endTime < nowTime) {
console.log("销毁")
return cancelAnimationFrame(timer);
}
console.log(`${mm}`.replace(/^\d$/, '0$&'),`${ss}`.replace(/^\d$/, '0$&'))
};
if (endTime && endTime > Math.ceil(new Date().getTime())) {
timer= requestAnimationFrame(setLeftTime);
}
return () => {
// 清除定时器
console.log('销毁@------@')
cancelAnimationFrame(timer);
};
}, [endTime]);
return {
days,hours,minutes,seconds,
};
}
结论:经测试,从图中确实可以看出,当离开页面的时候,requestAnimationFrame中的代码暂停执行,减少了资源的消耗