countDown+react+hook

道阻且长,行而不辍,未来可期

知识点一:
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中的代码暂停执行,减少了资源的消耗

相关推荐
MSTcheng.10 分钟前
【C++】C++11新特性(二)
java·开发语言·c++·c++11
晓131313 分钟前
第七章 【C语言篇:文件】 文件全面解析
linux·c语言·开发语言
愚者游世13 分钟前
Delegating Constructor(委托构造函数)各版本异同
开发语言·c++·程序人生·面试·改行学it
梵刹古音16 分钟前
【C语言】 指针基础与定义
c语言·开发语言·算法
Ekehlaft19 分钟前
这款国产 AI,让 Python 小白也能玩转编程
开发语言·人工智能·python·ai·aipy
rit843249921 分钟前
MATLAB中Teager能量算子提取与解调信号的实现
开发语言·matlab
开源技术24 分钟前
Python GeoPandas基础知识:地图、投影和空间连接
开发语言·ide·python
hedley(●'◡'●)27 分钟前
基于cesium和vue的大疆司空模仿程序
前端·javascript·vue.js·python·typescript·无人机
Cult Of27 分钟前
Alicea Wind的个人网站开发日志(2)
开发语言·python·vue
qq5_81151751529 分钟前
web城乡居民基本医疗信息管理系统信息管理系统源码-SpringBoot后端+Vue前端+MySQL【可直接运行】
前端·vue.js·spring boot