道阻且长,行而不辍,未来可期
知识点一:
new Date().getTime()
可以得到得到1970年01月1日0点零分以来的毫秒数。单位是毫秒
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:
const { days, hours, minutes, seconds } = useCountDown2(new Date("2023-08-22T03:35:00.000Z").getTime());
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中的代码暂停执行,减少了资源的消耗