JS手写防抖与节流

2023-05-16

1.概念:

防抖:指定内只执行一次,如果指定时间内再次被触发,则重新开始计时。实现主要需要利用闭包,定时器,arguments和this指向,立即执行。

节流:隔一段时间执行一次,如果指定时间内再次被触发,则不执行,指定时间后才继续执行。实现主要需要利用闭包,定时器(隔一段时间执行一次)/时间戳(立即执行),arguments和this指向。

2.防抖

简单版:

function debounce(func, wait){
    let timerId = null;
    return function(){
        let _This = this,
            args = arguments;
         if(timerId) clearTimeout(timerId);
         timerId = setTimeout(function(){
            func.apply(_This,args);
            },wait);
    }
}

立即执行:

document.addEventListener('mousemove', _.debounce(handleMouseMove, 60));
function debounce(func, wait, immadiate){
    let timerId = null;
    return function(){
       let _This = this,
           args = arguments;
        if(timerId) clearTimeout(timerId);

        if(immadiate){
            //callNow也可表示第一次执行,第一次是true,会重新设置定时器,且func.apply(_This, args),后续为false且在指定时间内重新创建定时器,直到指定时间结束
            let callNow = !timerId;
            timerId = setTimeout(function(){
               timerId = null;
            },wait);
            if(callNow) func.apply(_This,args);
        }else{
            timerId = setTimeout(function(){
                func.apply(_This,args);
            },wait);
        }
    }
}

3.节流

时间戳方式:

立即执行,停止触发后不会最后再执行一次

function throttle(func, wait) {
    let lastCallTime = Date.now(); //也可以用new Date().valueof()

    return function() {
        let _This = this,
            args = arguments,
            curCallTime = Date.now();
        //只在时间到了以后,重新执行函数且重新计时
        if (curCallTime - lastCallTime >= wait) {
            func.apply(_This, args);
            lastCallTime = Date.now();
        }
    }
}

定时器方式:

不立即执行,隔段时间执行一次

function throttle(func, wait){
    let timerId = null;
    return function(){
        let _This = this,
            args = arguments;
        if(!timerId){
            timerId = setTimeout(function(){
                func.apply(_This,args);
                timerId = null;
            },wait);
        }
    }
}

时间戳和定时器结合方式:

同时利用时间戳立即执行和定时器可以隔段时间执行的优点

function throttle(func, wait){
    let lastCallTime = Date.now();
    let timerId = null;
    return function(){
        let _This = this,
            args = arguments,
            curCallTime = Date.now();
        
        if(curCallTime- lastCallTime >= wait){
            if(timerId) clearTimeout(timerId);
            func.apply(_This,args);
            lastCallTime = Date.now();
        }
        if(!timerId){
            lastCallTime = Date.now();
            timerId = setTimeout(function(){
            func.apply(_This,args);
                timerId = null;
            },wait);
        } 
    }
}

第三个参数设置第一次或最后一次是否执行:

/**
 * 将时间戳和定时器结合
 * @param {*} func 
 * @param {*} wait 
 * @param {*} options (leading:第一次是否执行  trailing:离开时是否执行 ) 
 * @returns 
 */
function throttle(func, wait, options) {
    let _This, args, timer;
    let lastCallTime = Date.now();
    //如果没有设置第三个参数,那么第三个参数为空对象
    if (!options) options = {};

    return function() {
        _This = this;
        //获取当前函数的实参
        args = arguments;
        //获得时间戳
        let curTime = Date.now();

        if (options.leading === false && !lastCallTime) {
            lastCallTime = curTime;
        }

        //在首次进入的时候,能够保证立即执行。
        if (curTime - lastCallTime > wait) {
            if (timer) clearTimeout(timer);
            func.apply(_This, args);
            lastCallTime = curTime;
        };
        //在后续的执行过程中完成每wait时间内,执行一次。
        if (!timer && options.trailing !== false) {
            timer = setTimeout(function() {
                lastCallTime = Date.now();
                func.apply(_This, args);
                timer = null;
            }, wait)
        }
    };
}
document.addEventListener('mousemove', _.throttle(handleMouseMove, 1000, {
    leading: true,
    trailing: true
}));

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JS手写防抖与节流 的相关文章

  • MPU6050误差分析

    MPU6050模块 xff0c 如图 1所示 该模块集成了一片MPU6050芯片和一片STM8S003F3P6单片机 xff0c 具有串口和I2C接口 MPU6050中的DMP xff08 数字运动处理器 xff09 对姿态进行融合 xff
  • 为什么面试要问底层原理自我看法

    每次面试时别人都会问一些底层问题 但如果面试上后 xff0c 去公司写的还是业务代码 为什么要这样呢 xff0c 我面试过很多公司 xff0c 但是很少有面试官知道为什么要去问底层 只是他们知道别人都在问 xff0c 那我也要问 xff0c
  • 有意思的字符串查找函数strchr,strrchr,strstr,strrstr

    通过一段时间对字符串的了解 xff0c 我发现了许多有意思的字符串函数 xff0c 下面我们就以常见的字符串查找函数 strchr strrchr strstr strrstr为例来模拟实现这些有意思的字符串查找函数吧 xff01 strc
  • Gazebo相关内容学习

    什么是Gazebo和ros 以及二者的关系 xff1f Gazebo是一个不错的仿真工具 xff0c 它使用物理引擎模拟真实的世界 xff0c 使得我们可以通过仿真的方式从原理上验证算法 xff0c 计算负载和受力情况 xff0c 进而指引
  • SLAM_ROS算法包运行---gazebo仿真和实际场景

    SLAM学习交流可加群 xff1a 248085206 1 rtabmap算法简介 rtabmap全名是Real Time Appearance Based Mapping 是一个基于RGB D Stereo和雷达的Graph Based
  • 【Ubuntu】aptitude命令详解

    aptitude aptitude 与 apt get 一样 xff0c 是 Debian 及其衍生系统中功能极其强大的包管理工具基于大名鼎鼎的APT机制 整合了 dselect 和 apt get 的所有功能 并提供的更多特性 特别是在依
  • PCIE2.0/PCIE3.0/PCIE4.0/PCIE5.0接口的带宽、速率计算

    一 PCIE接口速率 xff1a 二 PCIE相关概念 xff1a 传输速率为每秒传输量GT s xff0c 而不是每秒位数Gbps xff0c 因为传输量包括不提供额外吞吐量的开销位 xff1b 比如 PCIe 1 x和PCIe 2 x使
  • git子模块使用-添加,更新,删除

    git子模块使用 添加 xff0c 更新 xff0c 删除 前言添加子模块初始化子模块更新子模块删除子模块更新子模块 前言 刚刚入职新公司 xff0c 老大说我们公司用git子模块 xff0c 说让我研究一下这个 xff0c 当时我就蒙蔽了
  • ARM和STM32的区别

    STM32与通常ARM的区别 经常有人问到 STM32和ARM以及ARM7是什么关系这样的问题 xff0c 其实ARM是一个做芯片标准的公司 xff0c 它负责的是芯片内核的架构设计 xff0c 而 TI xff0c ST这样的公司 xff
  • 动态目标检测与跟踪

    目标跟踪学习1 文章目录 目标跟踪学习1前言一 安装软件1 Visual Studio2019安装2 opencv的安装 二 使用步骤1 项目配置2 配置HCNetSDKV和ffmpeg以及videoinput2 程序运行 总结 前言 随着
  • FreeROTS了解(三)

    1 中断 xff08 1 xff09 先优先级分组 3位作为抢占优先级 xff0c 1位作为子优先级 0 7是抢占优先级的数值 xff0c 0 1是子优先级的数值 NVIC SetPriorityGrouping 4 xff08 2 xff
  • 论文仿真心得

    最近在做论文仿真 xff0c 有点让人头疼 xff0c 感觉要实现一篇论文的算法不是那么容易 根据近期的经验 xff0c 总结如下 xff1a 1 首先上网搜搜 有没有已经实现的代码 xff0c 能够搜到则会让你轻松很多 xff1b 2 在
  • zed双目摄像头使用--sdk的安装

    刚开始安装的时候 xff0c 需要cuda xff0c 这个看你选择了哪一个版本的sdk xff0c 可以在官网上下载 因为在windows上试了一下 xff0c 我使用了优盘上cuda7 5的版本的 xff0c 结果安装上 xff0c 没
  • 服务器中使用Docker容器显示图形界面GUI到本地

    因为系统装了16的ubuntu系统 xff0c 但是open3d目前显示功能只是支持18及以上的系统 xff0c 所以用来docker容器 xff0c 为了有显示 xff0c 我采用了其他博主提到的第二种方法 xff0c 第一种没成功 xf
  • docker中创建VNC,连接docker中VNC没xfce桌面然后还打不开terminal的情况,解决中文乱码

    第一步 xff0c 先创建容器 xff0c 然后确定绑定的路径 span class token function docker span run gpus all it v data Bill Bill v etc apt home et
  • ubuntu18安装 g2o_viewer 安装 ,报错 The constructor with a sharewidget is deprecated

    参考 xff1a https blog csdn net billbliss article details 77864695 https blog csdn net ktigerhero3 article details 75457432
  • EKF SLAM 以及MSCKF 学习

    参考 xff1a https zhuanlan zhihu com p 21381490 https citeseerx ist psu edu viewdoc download jsessionid 61 FA1024834F74311E
  • MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)如何理解

    在mianWindow cpp中第一行代码如下 MainWindow MainWindow QWidget parent QMainWindow parent 这是C 43 43 继承 xff0c 说明 MainWindow 的构造函数之前
  • 点云配准NDT以及CPD方法

    这些方法都是精匹配的方法 xff0c 主要就是找对应关系还是有初值 NDT xff08 Normal Distributions Transform xff09 xff0c 找到对应关系之后 xff0c 一个栅格里面有一个高斯函数 xff0

随机推荐