一、防抖
函数在 一定时间 内再次被触发,将重新开始 延时 执行,称为函数防抖。
从定义上不难看出,函数防抖应该出现在有定时器的函数当中。
举个例子,当下面的按钮在一秒内被点击多次后,点击了几次则会输出几次1,
希望的结果是:只要一秒内再次点击按钮,直到最后一次点击结束后的一秒才输出结果。
1 function fun(){ 2 setTimeout(function(){ 3 console.log(1) 4 },1000) 5 } 6 $('button').on('click',function(){ 7 fun() 8 })
思路就是在点击事件触发后先清除定时器:
function fun(){ let timer clearTimeout(timer) timer = setTimeout(function(){ console.log(1) },1000) }
但清除定时器的时候,定时器还没有被定义,所以我们要访问内存中存储的定时器,
而访问内存中的数据,须通过闭包实现,可以对函数进行如下改造:
function fun(){ let timer return function(){ clearTimeout(timer) //访问fun中的局部变量timer timer = setTimeout(function(){ console.log(1) },1000) } } var fn = fun()//接收返回的函数 $('button').on('click',function(){ fn()//调用接收的函数 })
添加回调函数cb(callback),可以把函数定义在定时器外。
function fun(callback){ let timer return function(){ clearTimeout(timer) timer = setTimeout(function(){ callback() },1000) } } function cb(){ console.log(1) } var fn = fun(cb) $('button').on('click',function(){ fn() })
二、节流
节流与防抖类似,在规定时间内只能触发一次函数。
思路是:获取触发函数的时间戳,若触发时间-上次触发时间>规定的时间,才能执行函数。
由于每次都要访问上次的触发时间,故也需要采用闭包。
function fun(){ console.log(1) } $('button').on('click',trottle(fun,2000)) function trottle(fn,delay){ var begin = 0 return function(){ var cur = new Date().getTime() if(cur - begin > delay){ fn() begin = cur } } }