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

相关推荐
萌萌哒草头将军2 分钟前
🚀🚀🚀Prisma 发布无 Rust 引擎预览版,安装和使用更轻量;支持任何 ORM 连接引擎;支持自动备份...
前端·javascript·vue.js
luojiaao11 分钟前
【Python工具开发】k3q_arxml 简单但是非常好用的arxml编辑器,可以称为arxml杀手包
开发语言·python·编辑器
终焉代码11 分钟前
STL解析——list的使用
开发语言·c++
SoFlu软件机器人14 分钟前
智能生成完整 Java 后端架构,告别手动编写 ControllerServiceDao
java·开发语言·架构
狼性书生16 分钟前
uniapp实现的简约美观的星级评分组件
前端·uni-app·vue·组件
书语时19 分钟前
ES6 Promise 状态机
前端·javascript·es6
英英_21 分钟前
视频爬虫的Python库
开发语言·python·音视频
猛犸MAMMOTH26 分钟前
Python打卡第46天
开发语言·python·机器学习
拉不动的猪1 小时前
管理不同权限用户的左侧菜单展示以及权限按钮的启用 / 禁用之其中一种解决方案
前端·javascript·面试
多多*1 小时前
微服务网关SpringCloudGateway+SaToken鉴权
linux·开发语言·redis·python·sql·log4j·bootstrap