防抖和节流是在前端开发中经常用到的技术,用于对频繁触发的行为进行频率或者次数的限制
在前端开发的过程中,我们经常会需要绑定一些持续触发的事件,如 resize、scroll、mousemove 等等,但有些时候我们并不希望在事件持续触发的过程中那么频繁地去执行函数
通常这种情况下防抖和节流是比较好的解决方案 , 防抖是控制次数,节流是控制频率
防抖
封装运动函数的时候:在开启一个新的定时器之前先清除定时器,这样动画效果就不会叠加了
let timer = null function animate () { clearInterval(timer) timer = setInterval(() => { // .... }, 20) }
表单验证的时候:延迟验证,如果300ms以内再次触发keyup事件就清除定时器,只有最后一次输入才会触发验证
input.onkeyup = function () { clearTimeout(this.timer) this.timer = setTimeout(() => { // ...验证逻辑... }, 300) }
节流
思路: 第一次先设定一个变量true,第二次执行这个函数时,会判断变量是否true,是则返回。当第一次的定时器执行完函数最后会设定变量为false。那么下次判断变量时则为false,函数会依次运行
function debounce(func, wait=1000){ //可以放入项目中的公共方法中进行调用 func为需要节流的函数 let timeout; return function(event){ clearTimeout(timeout) timeout = setTimeout(()=>{ func.call(this, event) },wait) } }
let isMove = false div.onmousemove = function () { if (!isMove) { isMove = true clearTimeout(this.timer) this.timer = setTimeout(() => { // ...逻辑代码... isMove = false }, 100) } }
函数防抖:将几次操作合并为一此操作进行。原理是维护一个计时器,规定在delay时间后触发函数,但是在delay时间内再次触发的话,就会取消之前的计时器而重新设置。这样一来,只有最后一次操作能被触发。
函数节流:使得一定时间内只触发一次函数。原理是通过判断是否到达一定时间来触发函数。
区别: 函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而函数防抖只是在最后一次事件后才触发一次函数。 比如在页面的无限加载场景下,我们需要用户在滚动页面时,每隔一段时间发一次 Ajax 请求,而不是在用户停下滚动页面操作时才去请求数据。这样的场景,就适合用节流技术来实现。