三分钟弄懂防抖节流函数

 页面:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>index</title>
</head>
<body>
    <button id="btn">发送验证码</button>
</body>
<script>
    const btn = document.getElementById("btn");
    btn.onclick = function(){
        console.log("已发送");
    }
</script>
</html>

点击按钮时,点一次会在控制台在打印一次已发送.

假设每一次打印就是一次验证码请求,这样短信请求太多,现要求60s内只能请求一次验证码

按钮节流

const btn = document.getElementById("btn");

let flag = true;

if(flag){
    btn.onclick = function(){
        console.log("已发送");
        this.innerHTML = "多次点击无效";
        flag = false;
        setTimeout(() => {
            flag = true;
            this.innerHTML = "发送验证码";
        },60000)
    }
}

 

60s后

 

 

函数调用节流

时间戳节流

一定时间内,只执行第一次,点击立即执行

//参数:要节流的函数,间隔时间
function a(fn,interval){
  //定义上一次节流结束时间
  let last = 0;
  return function(){
    //得到当前时间
    let now = Date.now();
    //当前时间 - 结束时间 > 间隔时间    执行函数
    if(now - last >= interval){
        fn.apply(this,arguments);
        //重新赋值结束时间
        last = now;
    }
  }
}
const btn = document.getElementById("btn");

function click(){
    console.log("已发送");
}

const c = a(click,60000);

btn.onclick = c;

一直按按钮,60s内只会执行一次

定时器节流

一定时间内,只执行第一次,时间到后执行

function a(fn,interval){
  let timer = null;
  return function(){
    let that = this;
    let args = arguments;
    if(!timer){
    	timer = setTimeout(() => {
      	fn.apply(that,args);
      	timer = null
    	},interval)
  	}
  }
}
const btn = document.getElementById("btn");

function click(){
    console.log("已发送");
}

const c = a(click,60000);

btn.onclick = c;

点击按钮后,结果一片空白,60s后执行函数,执行后再次点击重新进入60s等待

 

时间戳 + 定时器 节流

间隔时间内,点击立即执行一次,多次点击会记录最后一次点击

最后一次点击事件 + 间隔时间后执行一次

function a(fn,delay){
  let timer = null;
  let startTime = Date.now();
  
  return function(){
    //记录当前时间
    let curTime = Date.now();
    //记录运行时间
    let remainning = delay - (curTime - startTime);
    
    let that = this;
    let args = arguments;
    clearTimeout(timer);
    //节流结束,一个新的节流函数走这里
    if(remainning <= 0){
    	fn.apply(that,args);
      startTime = Date.now();
    }else {
    //节流没结束,给最后一次调用绑定延迟
      timer = setTimeout(fn,remainning);
    }
  }
}
const btn = document.getElementById("btn");

function click(){
    console.log("已发送");
}

const c = a(click,60000);

btn.onclick = c;

60s内点击了四次,结果:

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值