手写节流throttle

节流throttle

应用场景
  • 滚动事件监听scroll:例如监听页面滚动到底部加载更多数据时,使用节流技术减少检查滚动位置的频率,提高性能。
  • 鼠标移动事件mousemove:例如实现一个拖拽功能,使用节流技术减少鼠标移动事件的处理频率。
  • 动画效果:当实现一个基于时间的动画效果时,使用节流技术限制动画帧率,降低计算开销。

它使用了闭包和setTimeout来确保函数fn在指定的delay时间内只被调用一次,即使它被频繁触发。这里是对您代码的一个详细解释:

有很多其他的实现方式....比对时间戳

定时器版
function throttle(fn, delay) {  
  // 创建一个标志位canRun,默认为true,表示函数可以被执行  
  let canRun = true;  
  
  // 返回一个新的函数,这个函数会包裹原来的fn函数  
  return function(...args) {  
    // 如果canRun为false,说明上一次fn的执行还没有完成,直接返回不执行  
    if (!canRun) {  
      return;  
    }  
  
    // 在函数执行前将canRun设为false,表示fn正在执行或等待执行  
    canRun = false;  
  
    // 使用setTimeout来设置一个延时,确保fn在delay时间后执行  
    // 注意:这里的this和args都是从外部函数捕获的,它们代表了原始事件处理函数的上下文和参数  
    setTimeout(() => {  
      // 在delay时间后,执行fn函数,并恢复canRun为true,表示可以再次执行fn  
      fn.apply(this, args);  
      canRun = true;  
    }, delay);  
  };  
}  
  
// 使用示例  
const handleScroll = throttle(function() {  
  console.log('Scroll event handled.');  
}, 200); // 设置节流间隔为200毫秒  
  
window.addEventListener('scroll', handleScroll);

在这个例子中,handleScroll是节流后的函数,它被用作scroll事件的处理程序。无论用户如何频繁地滚动页面,handleScroll函数都只会每200毫秒执行一次,从而有效地减少了不必要的计算和DOM操作,提高了页面的性能。

<!DOCTYPE html>  
<html lang="en">  
<head>  
<meta charset="UTF-8">  
<meta name="viewport" content="width=device-width, initial-scale=1.0">  
<title>Throttle Scroll Event Example</title>  
<style>  
  /* 为了演示,我们可以添加一些样式使页面更长 */  
  body {  
    height: 2000px;  
  }  
</style>  
</head>  
<body>  
<!-- 为了演示,这里添加一些内容使页面更长 -->  
<div style="height: 1000px;">Scroll down to see the throttled scroll event handler in action.</div>  

<script>  
    // 定义节流函数  
    function throttle(fn, delay) {  
      let canRun = true;  
      return function(...args) {  
        if (!canRun) {  
          return;  
        }  
        canRun = false;  
        setTimeout(() => {  
          fn.apply(this, args);  
          canRun = true;  
        }, delay);  
      };  
    }  
      
    // 定义滚动事件处理函数  
    function handleScroll() {  
      console.log('Scroll event handled at', new Date().toISOString());  
      // 这里可以添加实际的滚动处理逻辑,比如加载更多内容、改变样式等  
    }  
      
    // 使用节流函数包装滚动事件处理函数  
    const throttledScrollHandler = throttle(handleScroll, 2000); // 设置节流间隔为200毫秒  
      
    // 添加滚动事件监听器  
    window.addEventListener('scroll', throttledScrollHandler);  
    </script>  
      
</body>  
</html>

演示

补充:

时间戳版
  • 原理:通过比较当前时间和上一次执行函数的时间戳,来判断是否达到指定的时间间隔。
  • 示例代码
function throttle(func, wait) {  
  let previous = 0;  
  return function() {  
    let now = Date.now();  
    let context = this;  
    let args = arguments;  
    if (now - previous > wait) {  
      func.apply(context, args);  
      previous = now;  
    }  
  }  
}  
  
// 使用方法  
content.onmousemove = throttle(count, 1000); // 每1秒执行一次count函数
使用lodash库
  • 示例代码
html复制代码



<script src="./lodash.min.js"></script>  
<script>  
  const box = document.querySelector('.box');  
  let i = 1;  
  function mouseMove() {  
    box.innerHTML = i++; // 如果里面存在大量操作DOM的情况,可能会卡顿  
  }  
  box.addEventListener('mousemove', _.throttle(mouseMove, 500)); // 每500毫秒执行一次mouseMove函数  
</script>

节流防抖的区别

节流throttle指定的delay时间内只被调用一次,即使它被频繁触发;

防抖debounce,只要触发,就重新计算delay;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/685296.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

封装了一个仿照抖音评论轮播效果的iOS轮播视图

效果图 原理 就是我们在一个视图里面有两个子视图&#xff0c;一个是currentView, 一个是willShowView,在一次动画过程中&#xff0c;我们改变current View的frame&#xff0c;同时改变willShowView的frame&#xff0c;同时&#xff0c;需要改变currentVIew 的transform.y不然…

酒店旅游API服务汇总

各大旅游平台常用API服务汇总&#xff1a; 实时房源服务【Airbnb】飞猪旅行开放服务途牛旅行开放平台API华为云数字差旅【差旅管理】动态信息接口【美团酒店】旅行商城商家管理API【马蜂窝】交易流程接口【美团酒店】电子导游【携程旅行】

【Linux】磁盘文件和软硬链接

上篇博客我们说了内存级文件&#xff0c;就是文件加载到内存中它的一些操作。那么不可能所有文件文件都要加载到内存中&#xff0c;大部分文件都要存在与一种可以永久性存储数据的硬件中&#xff0c;就是我们要说的磁盘。现在的笔记本电脑用的都是硬盘&#xff0c;你可以理解为…

12. MySQL 日志

文章目录 【 1. 日志的基本原理 】【 2. 错误日志 Error Log 】2.1 启动和设置错误日志2.2 查看错误日志2.3 删除错误日志 【 3. 二进制日志 Binary Log 】3.1 启动和设置二进制日志3.2 查看二进制日志3.3 删除二进制文件删除所有二进制日志删除小于指定编号的二进制日志删除创…

ICPC2024 邀请赛西安站(7/8/13)

心得 [ICPC2024 Xian I] ICPC2024 邀请赛西安站重现赛 - 比赛详情 - 洛谷 7表示赛时ac了7个&#xff0c;8表示含补题总共ac数&#xff0c;13表示题目总数 题目 M. Chained Lights 打表&#xff0c;发现只有k1是YES //#include <bits/stdc.h> #include<iostream&…

LCTF 2018 bestphp‘s revenge

考点:Soap原生类Session反序列化CRLF注入 <?php highlight_file(__FILE__); $b implode; call_user_func($_GET[f], $_POST); session_start(); if (isset($_GET[name])) { $_SESSION[name] $_GET[name]; } var_dump($_SESSION); $a array(reset($_…

路由黑洞处理

今天BGP基础实验碰到了路由黑洞 BGP承载于IGP之上&#xff0c;BGP路由天生要递归&#xff0c;才能找出口 在E的BGP去A&#xff0c;下一跳只有B&#xff0c;但是流量走了两条路&#xff0c;c和d BGP路由黑洞&#xff1a; 控制层面可达&#xff0c;数据层面不可达; 路由条目在BG…

查看远程桌面端口,查看服务器的远程桌面端口的方法

如果你正在寻找一种方法来检查服务器的远程桌面端口&#xff0c;那么请务必按照以下步骤操作&#xff0c;以确保准确且安全地获取所需信息。这不仅是一个技术问题&#xff0c;更是一个关于效率和安全性的重要议题。 首先&#xff0c;你需要明确&#xff0c;远程桌面端口通常是…

C++之第十一课

课程列表 十分抱歉拖更了这么久&#xff0c;在之前的第十课里也有网友反馈了一个问题&#xff1a; 说的没错&#xff0c;怪我在审稿时没有注意图片&#xff0c;所以这里修正一下&#xff1a; 在此也十分感谢“我有一些感想……”网友的提醒&#xff01; 好了&#xff0c;回到…

【MySQL调优】如何进行MySQL调优?从参数、数据建模、索引、SQL语句等方向,三万字详细解读MySQL的性能优化方案(2024版)

导航&#xff1a; 本文一些内容需要聚簇索引、非聚簇索引、B树、覆盖索引、索引下推等前置概念&#xff0c;虽然本文有简单回顾&#xff0c;但详细可以参考下文的【MySQL高级篇】 【Java笔记踩坑汇总】Java基础进阶JavaWebSSMSpringBoot瑞吉外卖SpringCloud黑马旅游谷粒商城学成…

Linux——内存管理代码分析

虚空间管理 页框和页的关系 页框 将内存空间分为一个个大小相等的分区(比如:每个分区4KB),每个分区就是一个页框&#xff0c;也叫页帧&#xff0c;即物理页面&#xff0c;是linux划分内存空间的结果。 每个页框都有一个页框号&#xff0c;即内存块号、物理块号。 页 将用户…

app自动识别ios或安卓手机,微信浏览器,并下载相应的apk安装包

来源是安卓下载界面显示: 来源是IOS下载界面显示: 源码 <!DOCTYPE html> <html lang="en"><head

流水线建构apk、abb实战(二)

gradlew 命令生成apk、aab包 其实构建应用程序包就几个命令&#xff1a; ### 生成AAB&#xff1a; gradlew bundleRelease #输出到[project]/build/outputs/bundle/release/下 gradlew bundleDebug### 生成APK&#xff1a; gradlew assembleRelease gradlew assembleDebug###…

今日arXiv最热大模型论文:大模型都能怎么用?中南大学最新综述:大模型时代的自然语言处理

还记得2022年末ChatGPT的横空出世&#xff0c;带来了整个NLP乃至AI领域的震动&#xff0c;随后如LLaMA、ChatGLM、Qwen等类ChatGPT大模型&#xff08;LLM&#xff09;开始如雨后春笋般涌现&#xff0c;这些先进的模型不仅展示了在零样本学习中的出色表现&#xff0c;还在多种NL…

ToonCrafter——自动生成动画中间帧与动画上色

1、引言 动画制作对许多人来说都是一项专业且复杂的工作&#xff0c;需要学习专门的知识、掌握特定的工具&#xff0c;并投入大量的时间和精力才能获得成果。不过&#xff0c;最近推出的一款 AI 动画制作工具 ToonCrafter 有望改变这一现状。 它只需两张图像即可生成连贯流畅…

Turntin查重报告解读,如何根据颜色标准修改essay作业

留学生是学术生涯&#xff0c;撰写essay作业时是最常见的学习状态。在这样一个过程中&#xff0c;常常会遇到许多问题&#xff0c;当然&#xff0c;最需要注意便是抄袭问题。为了确定我们的essay符合标准&#xff0c;通常许多学生会选择使用Turnitin查重&#xff08;www.checkt…

神经网络搭建(1)----nn.Sequential

神经网络模型构建 采用CIFAR10中的数据&#xff0c;并对其进行简单的分类。以下图为例 输入&#xff1a;3通道&#xff0c;3232 ( 经过一个55的卷积) → 变成32通道&#xff0c;3232的图像 (经过22的最大池化) → 变成32通道&#xff0c;1616的图像 ( 经过一个55的卷积) → 变…

英伟达再创历史,市值超越苹果,跃居全球第二大上市公司

进入2024年&#xff0c;英伟达股价依然突飞猛进。 今天凌晨&#xff0c;英伟达凭借其在AI领域强劲的创新能力和市场势头&#xff0c;达成了历史性的里程碑——市值首次突破3万亿美元&#xff0c;成功超越苹果&#xff0c;成为全球市值第二大上市公司。 排名仅次于微软。 英伟达…

从零开始实现自己的串口调试助手(7) -隐藏面板/刷新串口号/实现多文本

隐藏/拓展面板/历史: ui界面操作: 选中隐藏面板按钮&#xff0c;勾选checkable 创建bool类型的槽函数 隐藏/拓展面板槽函数: void Widget::on_btnHideTable_clicked(bool checked) {if(checked){ui->btnHideTable->setText("拓展面板");ui->groupBoxTexts-…

Kotlin 网络请求小例子(Ktor)

文章目录 导入依赖创建 Http 客户端 其实还是借着 Ktor 学一学 Kotlin 如何导入依赖&#xff0c;这应该是我们 Kotlin 基础专栏的最后一期了。 Ktor 是 Kotlin 官方的一个网络请求库&#xff0c;它具有优秀且精炼的 API&#xff0c;并且是跨平台的。 本教程参考自 Ktor 文档 …