使用requestAnimationFrame写防抖和节流
debounce.ts
防抖工具函数:
function Animate() {this.timer = null;
}Animate.prototype.start = function (fn) {if (!fn) {throw new Error('需要执行函数');}if (this.timer) {this.stop();}this.timer = requestAnimationFrame(fn);
}Animate.prototype.stop = function () {if (!this.timer) {return;}cancelAnimationFrame(this.timer);this.timer = null;
}export default Animate;
注意:
以上是es5写法,也可以自行改成es6的class类写法
使用示例:
import React, { useState, useEffect } from 'react';
import Animate from 'utils/debounce';export default function UseTransition() {const [isAnimationFrame, setIsAnimationFrame]= useState(false);const [rangeValue, setRangeValue] = useState(1);const [renderData, setRenderData] = useState([1]);const [isPending, setIsPending] = useState(false);const animate = new Animate();const handleRange = (e) => {const value = parseInt(e.target.value, 10);setRangeValue(value);// 模拟 startTransition 的效果setIsPending(true);// 使用 requestAnimationFrame 模拟异步操作const fn = () => {const arr = Array(value).fill(null).map((_, index) => index + 1);setRenderData(arr);setIsPending(false);animate.stop();}// 1000/60动画帧频率isAnimationFrame ? animate.start(fn): fn();};useEffect(() => {return () => {isAnimationFrame && animate.stop();};}, []);const jsx = renderData.map((item) => (<divkey={item}style={{width: 20,height: 20,backgroundColor: `#${Math.floor(Math.random() * 22222222).toString(16)}`,margin: 10,display: 'inline-block',}}>{item}</div>));return (<div><div style={{ textAlign: 'center' }}><label><inputtype="checkbox"checked={isAnimationFrame}onChange={(e) => {setIsAnimationFrame(e.target.checked)}}/>setIsAnimationFrame</label><inputtype="range"value={rangeValue}min={0}max={10000}style={{ width: 120 }}onChange={handleRange}/><span>进度条 {rangeValue}</span><span>{isPending ? 'loading' : ''}</span><hr /></div>{jsx}</div>);
}
throttle.ts
节流工具函数
function Animate() {this.timer = null;this.lastRun = 0;this.interval = 1000 / 60; // 默认每秒 60 帧,即约 16.67 毫秒
}Animate.prototype.start = function (fn, interval = 1000 / 60) {if (!fn) {throw new Error('需要执行函数');}this.interval = interval;// 高精度:performance.now() 返回的时间戳精度通常在微秒级别,而 Date.now() 的精度通常在毫秒级别。const now = performance.now();if (this.timer === null && (now - this.lastRun >= this.interval)) {this.lastRun = now;this.timer = requestAnimationFrame(() => {fn();this.timer = null;this.start(fn, interval); // 递归调用以继续动画});}
}Animate.prototype.stop = function () {if (!this.timer) {return;}cancelAnimationFrame(this.timer);this.timer = null;this.lastRun = 0;
}export default Animate;
使用示例:
import React, { useState, useEffect } from 'react';
import Animate from 'utils/throttle';export default function UseTransition() {const [isAnimationFrame, setIsAnimationFrame]= useState(false);const [rangeValue, setRangeValue] = useState(1);const [renderData, setRenderData] = useState([1]);const [isPending, setIsPending] = useState(false);const animate = new Animate();const handleRange = (e) => {const value = parseInt(e.target.value, 10);setRangeValue(value);// 模拟 startTransition 的效果setIsPending(true);// 使用 requestAnimationFrame 模拟异步操作const fn = () => {const arr = Array(value).fill(null).map((_, index) => index + 1);setRenderData(arr);setIsPending(false);animate.stop();}// 1000/60动画帧频率isAnimationFrame ? animate.start(fn, 1000/60): fn();};useEffect(() => {return () => {isAnimationFrame && animate.stop();};}, []);const jsx = renderData.map((item) => (<divkey={item}style={{width: 20,height: 20,backgroundColor: `#${Math.floor(Math.random() * 22222222).toString(16)}`,margin: 10,display: 'inline-block',}}>{item}</div>));return (<div><div style={{ textAlign: 'center' }}><label><inputtype="checkbox"checked={isAnimationFrame}onChange={(e) => {setIsAnimationFrame(e.target.checked)}}/>setIsAnimationFrame</label><inputtype="range"value={rangeValue}min={0}max={10000}style={{ width: 120 }}onChange={handleRange}/><span>进度条 {rangeValue}</span><span>{isPending ? 'loading' : ''}</span><hr /></div>{jsx}</div>);
}
防抖和节流的区别?
防抖(Debounce)
定义:
- 防抖是指在一系列连续的事件触发中,只在最后一次事件触发后的一段时间内执行一次回调函数。
特点:
- 忽略中间的调用,只在最后一次调用后执行。
- 适用于需要在用户操作结束后再执行某些操作的场景,例如输入框的搜索建议、窗口的 resize 事件等。
节流(Throttle)
定义:
- 节流是指在一定时间间隔内最多执行一次回调函数。
特点:
- 在指定的时间间隔内,无论触发多少次事件,最多只执行一次回调函数。
- 当前时间戳now 减去 上一次执行animate的时间戳lastRun的结果 >= 指定的时间间隔,则执行一次函数。
- 适用于需要在固定时间间隔内执行某些操作的场景,例如滚动事件、鼠标移动事件等。
相关文章:
使用requestAnimationFrame写防抖和节流
debounce.ts 防抖工具函数: function Animate() {this.timer null; }Animate.prototype.start function (fn) {if (!fn) {throw new Error(需要执行函数);}if (this.timer) {this.stop();}this.timer requestAnimationFrame(fn); }Animate.prototype.stop function () {i…...
Puppeteer 与浏览器版本兼容性:自动化测试的最佳实践
Puppeteer 支持的浏览器版本映射:从 v20.0.0 到 v23.6.0 自 Puppeteer v20.0.0 起,这个强大的自动化库开始支持与 Chrome 浏览器的无头模式和有头模式共享相同代码路径,为自动化测试带来了更多便利。从 v23.0.0 开始,Puppeteer 进…...
Java方法重写
在Java中,方法重写是指在子类中重新定义父类中已经定义的方法。以下是Java方法重写的基本原则: 子类中的重写方法必须具有相同的方法签名(即相同的方法名、参数类型和返回类型)。子类中的重写方法不能比父类中的原方法具有更低的…...
vscode通过.vscode/launch.json 内置php服务启动thinkphp 应用后无法加载路由解决方法
我们在使用vscode的 .vscode/launch.json Launch built-in server and debug 启动thinkphp应用后默认是未加载thinkphp的路由文件的, 这个就导致了,某些thinkphp的一些url路由无法访问的情况, 如http://0.0.0.0:8000/api/auth.admin/info这…...
Webserver(2.6)有名管道
目录 有名管道有名管道使用有名管道的注意事项读写特性有名管道实现简单版聊天功能拓展:如何解决聊天过程的阻塞 有名管道 可以用在没有关系的进程之间,进行通信 有名管道使用 通过命令创建有名管道 mkfifo 名字 通过函数创建有名管道 int mkfifo …...
四足机器人实战篇之一:波士顿spot机器人工程实现分析
系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录 系列文章目录前言一、机器人发展历史二、硬件系统及电机执行器篇硬件系统电机执行器传感器机处理器电气连接三、感知(视觉点云、局部地图、定位)篇1.深度相机获取…...
TensorFlow 预训练目标检测模型集合
Tensorflow 提供了一系列在不同数据集上预训练的目标检测模型,包括 COCO 数据集、Kitti 数据集、Open Images 数据集、AVA v2.1 数据集、iNaturalist 物种检测数据集 和 Snapshot Serengeti 数据集。这些模型可以直接用于推理,特别是当你对这些数据集中已…...
字符串的区别
C 和 Java 字符串的区别 最近 C 和 Java 在同步学习,都有个字符串类型,但二者不太一样,于是就做了些许研究。 在编程中,字符串作为数据类型广泛应用于不同的场景。虽然 C 和 Java 都允许我们处理字符串,但它们在字符…...
EMR Serverless Spark:一站式全托管湖仓分析利器
本文根据2024云栖大会实录整理而成,演讲信息如下: 演讲人: 李钰(绝顶) | 阿里云智能集团资深技术专家,阿里云 EMR 团队负责人 活动: 2024 云栖大会 AI - 开源大数据专场 数据平台技术演变 …...
Linux find 匹配文件内容
在Linux中,你可以使用find命令结合-exec或者-execgrep来查找匹配特定内容的文件。以下是一些示例: 查找当前目录及其子目录下所有文件内容中包含"exampleText"的文件: find . -type f -exec grep -l "exampleText" {} \…...
【Redis优化——如何优雅的设计key,优化BigKey,Pipeline批处理Key】
Redis优化——如何优雅的设计key,优化BigKey,Pipeline批处理Key 一、Key的设计1. 命名规范2. 长度限制在44字节以内 二、BigKey优化1. 查找bigkey2. 删除BigKey3. 优化BigKey 三、Pipeline批处理Key1. 单节点的Pipeline2. 集群下的Pipeline 一、Key的设计…...
数据结构与算法分析:你真的理解图算法吗——深度优先搜索(代码详解+万字长文)
一、前言 图是计算机科学中用来表示复杂结构信息的一种基本结构。本章我们会讨论一些通用的围表示法,以及一些频繁使用的图算法。本质上来说,一个图包含一个元素集合(也就是顶点),以及元素两两之间的关系(也就是边),由于应用范围所限,本章我们仅仅讨论简单图,简单围并不会如(a…...
LinkedList 分析
LinkedList 简介 LinkedList 是一个基于双向链表实现的集合类,经常被拿来和 ArrayList 做比较。关于 LinkedList 和ArrayList的详细对比,我们 Java 集合常见面试题总结(上)有详细介绍到。 双向链表 不过,我们在项目中一般是不会使用到 Link…...
【C/C++】模拟实现strlen
学习目标: 使用代码模拟实现strlen。 逻辑: strlen 需要输入一个字符串数组类型的变量,并且返回一个整型类型的数据。strlen 需要计算字符串数组有多少个元素。 代码1:使用计数器 #define _CRT_SECURE_NO_WARNINGS 1 #include&…...
mybatis从浅入深一步步演变分析
mybatis从浅入深一步步演变分析 版本一:不使用代理(非spring) package com.yimeng.domain;public class User {private int id;private String username;private String password;public int getId() {return id;}public void setId(int id…...
Java阶段三02
第3章-第2节 一、知识点 面向接口编程、什么是spring、什么是IOC、IOC的使用、依赖注入 二、目标 了解什么是spring 理解IOC的思想和使用 了解IOC的bean的生命周期 理解什么是依赖注入 三、内容分析 重点 了解什么是spring 理解IOC的思想 掌握IOC的使用 难点 理解IO…...
【Linux】掌握库的艺术:我的动静态库封装之旅
🌈个人主页:Yui_ 🌈Linux专栏:Linux 🌈C语言笔记专栏:C语言笔记 🌈数据结构专栏:数据结构 🌈C专栏:C 文章目录 1.什么是库1.2 认识动静态库1.2.1 动态库1.2.2…...
UE5动画控制 基础
素材 mixamo先去选择一个character 点击下载 就这个下载下来 然后选几个animation, 记得勾选 把动作下载了 without skin就是只要动作 然后把他们放在一个文件夹里先 UE里导入 找一个文件夹,直接拖拽进来那个character的fbx,默认配置就…...
流畅!HTMLCSS打造网格方块加载动画
效果演示 这个动画的效果是五个方块在网格中上下移动,模拟了一个连续的加载过程。每个方块的动画都是独立的,但是它们的时间间隔和路径被设计为相互协调,以创建出流畅的动画效果。 HTML <div class"loadingspinner"><…...
linux命令之top(Linux Command Top)
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 本人主要分享计算机核心技…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...
PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
