使用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)
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 本人主要分享计算机核心技…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...