vue中手动封装节流防抖(附加原理)
1 // 防抖 ---- 效果: 短时间内大量触发同一事件时,只执行一次函数
// 场景:搜索框内模糊查询时,只在最后输入完才查询(手速慢的别抬杠),需要防抖 2 export function _debounce(fn, delay) { 3 4 var delay = delay || 200; 5 var timer; 6 return function () { 7 var th = this; 8 var args = arguments; 9 if (timer) { 10 clearTimeout(timer); 11 } 12 timer = setTimeout(function () { 13 timer = null; 14 fn.apply(th, args); 15 }, delay); 16 }; 17 } 18 // 节流 ---- 短时间内大量触发同一事件,在函数执行完成一次之后,该函数在指定时间期限内不再执行,直至过了这个时间才生效
// 场景: 移动端滚动的过程中,在滚动过程中容易出现空白区域,需节流 19 export function _throttle(fn, interval) { 20 var last; 21 var timer; 22 var interval = interval || 200; 23 return function () { 24 var th = this; 25 var args = arguments; 26 var now = +new Date(); 27 if (last && now - last < interval) { 28 clearTimeout(timer); 29 timer = setTimeout(function () { 30 last = now; 31 fn.apply(th, args); 32 }, interval); 33 } else { 34 last = now; 35 fn.apply(th, args); 36 } 37 } 38 }
// 最直观区别:
// 大场景: 一个input框,在里面输入的时候,按住一个键不放
// 防抖: 永远不会执行
// 节流: 每隔一段时间执行一次
使用:
1. 先引入 import { _debounce, _throttle } from '(当前代码所在位置)'
2. 在methods中使用
1 methods: { 2 changefield: _debounce(function(_type, index, item) { 3 // do something ... 4 }, 200) 5 }
如此使用即可!(原理继续下翻)
---------------------------------分割线------------------------------
节流防抖理论:
产生原因:
- 向后台频繁发送数据,频繁触发,导致服务器压力较大
- 一些事件:window.onresize、window.mousemove 监听等,触发频率非常高,会造成浏览器性能问题
基于上述原因,节流和防抖的概念也就出来了:
- 共同点:都能防止事件频繁触发
- 不同点:节流:单位时间内,触发一次事件 防抖:单位时间内,触发最后一次事件
一、函数节流(throttle)
函数执行后,只有大于设定的执行周期后才会执行第二次。
频繁触发的函数,在规定时间内,只让函数触发的第一次生效,后面不生效。
原理:用时间戳判断是否已到回调该执行时间;记录上次执行的时间戳,每次触发事件执行回调,回调中判断当前时间戳距离上次执行时间戳的间隔是否已经到达规定时间段,如果是,则执行,并更新上次执行的时间戳,如此循环;
频繁触发的函数,在规定时间内,只让函数触发的第一次生效,后面不生效。
原理:用时间戳判断是否已到回调该执行时间;记录上次执行的时间戳,每次触发事件执行回调,回调中判断当前时间戳距离上次执行时间戳的间隔是否已经到达规定时间段,如果是,则执行,并更新上次执行的时间戳,如此循环;
函数节流的应用场景
- 需要间隔一定时间触发回调来控制函数调用频率:
- DOM 元素的拖拽功能实现(mousemove)
- 搜索联想(keyup)
- 计算鼠标移动的距离(mousemove)
- Canvas 模拟画板功能(mousemove)
- 射击游戏的 mousedown/keydown 事件(单位时间只能发射一颗子弹)
- 监听滚动事件判断是否到页面底部自动加载更多:给 scroll 加了 debounce 后,只有用户停止滚动后,才会判断是否到了页面底部;如果是 throttle 的话,只要页面滚动就会间隔一段时间判断一次
二、函数防抖(debounce)
频繁触发的函数,在规定时间内,只让最后一次生效,前面的不生效。
原理:第一次调用函数,创建一个定时器,在指定的时间间隔之后运行代码。当第二次调用该函数时,它会清除前一次的定时器并设置另一个。如果前一个定时器已经执行过了,这个操作就没有任何意义。然而,如果前一个定时器尚未执行,其实就是将其替换为一个新的定时器,然后延迟一定时间再执行。
函数防抖的应用场景
- 对于连续的事件响应我们只需要执行一次回调:
- 每次 resize/scroll 触发统计事件
- 文本输入的验证(连续输入文字后发送 AJAX 请求进行验证,验证一次就好)
节流防抖区别:
- 函数防抖的情况下,函数将一直推迟执行,造成不会被执行的效果;----按住一个键不放,就一直不执行
- 函数节流的情况下,函数将每隔 n 秒执行一次
例:
函数防抖:如果A在10:00:00开门走入电梯内(触发事件),如果后续没有人进入电梯,电梯将在5秒钟之后10:00:05关门(执行事件监听器)。这时如果B在10:00:04走入电梯内,电梯会在10:00:09才关门。
函数节流 :如果A在10:00:00开门走入电梯内(触发事件),如果后续没有人进入电梯,电梯将在5秒钟之后10:00:05关门(执行事件监听器)。这时如果B在10:00:04走入电梯内,电梯同样是在10:00:05关门。这个时间从第一个人进入电梯开始计时,不管在5秒之内进来多少人,电梯都会在10:00:05关门。如果一直没有人进来,则电梯不运行。
函数节流 :如果A在10:00:00开门走入电梯内(触发事件),如果后续没有人进入电梯,电梯将在5秒钟之后10:00:05关门(执行事件监听器)。这时如果B在10:00:04走入电梯内,电梯同样是在10:00:05关门。这个时间从第一个人进入电梯开始计时,不管在5秒之内进来多少人,电梯都会在10:00:05关门。如果一直没有人进来,则电梯不运行。
注: 转载于https://www.jianshu.com/p/c63b1d1fb0da