防抖debounce
防抖过程
当事件触发时,响应的函数不会立即出发,而是等待一定时间
当事件密集触发时,函数的触发就会频繁的推迟
只有等待了一段时间也没有事件触发,才会真正执行响应函数
应用场景
- 输入框中输入内容,搜索或者提交信息
- 频繁的点击按钮
- 监听浏览器的滚动事件
- 用户缩放浏览器的resize事件
实现方法
1.第三方库(lodash,underscore)
2.手写实现(立即控制+取消功能)
function debounce(fn,delay,immediate=false){// 记录定时器let timer=null;// 记录当前执行状态let isInvoke=false;const _debounce= function(...args){// 清除上一次定时器if(timer) clearTimeout(timer);if(!isInvoke&&immediate){// 开始立即实行fn.apply(this,args);isInvoke=true;}else{// 延迟执行timer=setTimeout(()=>{fn.apply(this,args);isInvoke=false;timer=null;},delay);}};// 取消抖动功能_debounce.cancel=function(){if(timer) clearTimeout(timer);isInvoke=false;timer=null;}return _debounce;}
节流throttle
节流过程
当事件触发时,会执行这个事件的响应函数
如果这个事件被频繁触发,那么节流函数会按照一定的频率来执行函数
不管在这个中间有多少次触发,执行函数的频率总是固定的
应用场景
监听页面的滚动事件
鼠标的移动事件
用户频繁点 击按钮操作
实现方式
1.利用定时器手动实现
function throttle(fn,interval){let isInvoke=false;function _throttle(...args){if(!isInvoke){isInvoke=true;fn.apply(this,args);setTimeout(()=>{isInvoke=false;},interval);}}return _throttle;}
2.利用时间戳手动实现(前置、后置控制+取消功能)
function throttle(fn,interval,option={leading:true,trailing:false}){let lastTime=0;let timer=null;const {leading,trailing}=option;function _throttle(...args){const nowTime=new Date().getTime();// 取消首次触发if(!leading && lastTime===0){lastTime=nowTime;}const remainTime=interval-(nowTime-lastTime);if(remainTime<=0){// 正常执行if(timer){clearTimeout(timer);timer=null;}fn.apply(this,args);lastTime=nowTime;}else if(trailing && !timer){// 开启后续触发timer=setTimeout(()=>{fn.apply(this,args);lastTime=!leading ? 0 : new Date().getTime();timer=null;},remainTime)}}// 取消后续触发功能_throttle.cancel=()=>{if(timer) clearTimeout(timer);timer=null;lastTime=0;}return _throttle;}
