当前位置: 首页 > news >正文

使用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 支持的浏览器版本映射&#xff1a;从 v20.0.0 到 v23.6.0 自 Puppeteer v20.0.0 起&#xff0c;这个强大的自动化库开始支持与 Chrome 浏览器的无头模式和有头模式共享相同代码路径&#xff0c;为自动化测试带来了更多便利。从 v23.0.0 开始&#xff0c;Puppeteer 进…...

Java方法重写

在Java中&#xff0c;方法重写是指在子类中重新定义父类中已经定义的方法。以下是Java方法重写的基本原则&#xff1a; 子类中的重写方法必须具有相同的方法签名&#xff08;即相同的方法名、参数类型和返回类型&#xff09;。子类中的重写方法不能比父类中的原方法具有更低的…...

vscode通过.vscode/launch.json 内置php服务启动thinkphp 应用后无法加载路由解决方法

我们在使用vscode的 .vscode/launch.json Launch built-in server and debug 启动thinkphp应用后默认是未加载thinkphp的路由文件的&#xff0c; 这个就导致了&#xff0c;某些thinkphp的一些url路由无法访问的情况&#xff0c; 如http://0.0.0.0:8000/api/auth.admin/info这…...

Webserver(2.6)有名管道

目录 有名管道有名管道使用有名管道的注意事项读写特性有名管道实现简单版聊天功能拓展&#xff1a;如何解决聊天过程的阻塞 有名管道 可以用在没有关系的进程之间&#xff0c;进行通信 有名管道使用 通过命令创建有名管道 mkfifo 名字 通过函数创建有名管道 int mkfifo …...

四足机器人实战篇之一:波士顿spot机器人工程实现分析

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 TODO:写完再整理 文章目录 系列文章目录前言一、机器人发展历史二、硬件系统及电机执行器篇硬件系统电机执行器传感器机处理器电气连接三、感知(视觉点云、局部地图、定位)篇1.深度相机获取…...

TensorFlow 预训练目标检测模型集合

Tensorflow 提供了一系列在不同数据集上预训练的目标检测模型&#xff0c;包括 COCO 数据集、Kitti 数据集、Open Images 数据集、AVA v2.1 数据集、iNaturalist 物种检测数据集 和 Snapshot Serengeti 数据集。这些模型可以直接用于推理&#xff0c;特别是当你对这些数据集中已…...

字符串的区别

C 和 Java 字符串的区别 最近 C 和 Java 在同步学习&#xff0c;都有个字符串类型&#xff0c;但二者不太一样&#xff0c;于是就做了些许研究。 在编程中&#xff0c;字符串作为数据类型广泛应用于不同的场景。虽然 C 和 Java 都允许我们处理字符串&#xff0c;但它们在字符…...

EMR Serverless Spark:一站式全托管湖仓分析利器

本文根据2024云栖大会实录整理而成&#xff0c;演讲信息如下&#xff1a; 演讲人&#xff1a; 李钰&#xff08;绝顶&#xff09; | 阿里云智能集团资深技术专家&#xff0c;阿里云 EMR 团队负责人 活动&#xff1a; 2024 云栖大会 AI - 开源大数据专场 数据平台技术演变 …...

Linux find 匹配文件内容

在Linux中&#xff0c;你可以使用find命令结合-exec或者-execgrep来查找匹配特定内容的文件。以下是一些示例&#xff1a; 查找当前目录及其子目录下所有文件内容中包含"exampleText"的文件&#xff1a; find . -type f -exec grep -l "exampleText" {} \…...

【Redis优化——如何优雅的设计key,优化BigKey,Pipeline批处理Key】

Redis优化——如何优雅的设计key&#xff0c;优化BigKey&#xff0c;Pipeline批处理Key 一、Key的设计1. 命名规范2. 长度限制在44字节以内 二、BigKey优化1. 查找bigkey2. 删除BigKey3. 优化BigKey 三、Pipeline批处理Key1. 单节点的Pipeline2. 集群下的Pipeline 一、Key的设计…...

数据结构与算法分析:你真的理解图算法吗——深度优先搜索(代码详解+万字长文)

一、前言 图是计算机科学中用来表示复杂结构信息的一种基本结构。本章我们会讨论一些通用的围表示法,以及一些频繁使用的图算法。本质上来说,一个图包含一个元素集合(也就是顶点),以及元素两两之间的关系(也就是边),由于应用范围所限,本章我们仅仅讨论简单图,简单围并不会如(a…...

LinkedList 分析

LinkedList 简介 LinkedList 是一个基于双向链表实现的集合类&#xff0c;经常被拿来和 ArrayList 做比较。关于 LinkedList 和ArrayList的详细对比&#xff0c;我们 Java 集合常见面试题总结(上)有详细介绍到。 双向链表 不过&#xff0c;我们在项目中一般是不会使用到 Link…...

【C/C++】模拟实现strlen

学习目标&#xff1a; 使用代码模拟实现strlen。 逻辑&#xff1a; strlen 需要输入一个字符串数组类型的变量&#xff0c;并且返回一个整型类型的数据。strlen 需要计算字符串数组有多少个元素。 代码1&#xff1a;使用计数器 #define _CRT_SECURE_NO_WARNINGS 1 #include&…...

mybatis从浅入深一步步演变分析

mybatis从浅入深一步步演变分析 版本一&#xff1a;不使用代理&#xff08;非spring&#xff09; 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】掌握库的艺术:我的动静态库封装之旅

&#x1f308;个人主页&#xff1a;Yui_ &#x1f308;Linux专栏&#xff1a;Linux &#x1f308;C语言笔记专栏&#xff1a;C语言笔记 &#x1f308;数据结构专栏&#xff1a;数据结构 &#x1f308;C专栏&#xff1a;C 文章目录 1.什么是库1.2 认识动静态库1.2.1 动态库1.2.2…...

UE5动画控制 基础

素材 mixamo先去选择一个character 点击下载 就这个下载下来 然后选几个animation&#xff0c; 记得勾选 把动作下载了 without skin就是只要动作 然后把他们放在一个文件夹里先 UE里导入 找一个文件夹&#xff0c;直接拖拽进来那个character的fbx&#xff0c;默认配置就…...

流畅!HTMLCSS打造网格方块加载动画

效果演示 这个动画的效果是五个方块在网格中上下移动&#xff0c;模拟了一个连续的加载过程。每个方块的动画都是独立的&#xff0c;但是它们的时间间隔和路径被设计为相互协调&#xff0c;以创建出流畅的动画效果。 HTML <div class"loadingspinner"><…...

linux命令之top(Linux Command Top)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 本人主要分享计算机核心技…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

Xshell远程连接Kali(默认 | 私钥)Note版

前言:xshell远程连接&#xff0c;私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

12.找到字符串中所有字母异位词

&#x1f9e0; 题目解析 题目描述&#xff1a; 给定两个字符串 s 和 p&#xff0c;找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义&#xff1a; 若两个字符串包含的字符种类和出现次数完全相同&#xff0c;顺序无所谓&#xff0c;则互为…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

基于matlab策略迭代和值迭代法的动态规划

经典的基于策略迭代和值迭代法的动态规划matlab代码&#xff0c;实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...