在一些常见的触发resize事件和scroll的情况下,我们会使用函数防抖,来控制函数的触发次数,因为resize实时在变化,那函数就要实时在触发,这会带来一个致命的问题,对一些机型老旧的电脑,有可能使浏览器卡顿,下面我们来看一个例子
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>js之函数节流防抖</title> <style> * {padding: 0; margin: 0;} .box { 800px;height: 1200px;} </style> </head> <body> <div class="container"> <div class="box" style="background: black"></div> <div class="box" style="background: blue"></div> </body> <script> window.onload = function() { let num = 0 function scrollTap() { num++ console.log('num为 ${num}') } document.addEventListener('scroll', scrollTap) } </script> </html>
此时我们可以看到每次scroll事件触发时,num的值会发生变化,这会加重cpu的负担,造成性能问题,但是当我们使用防抖函数时,我们就可以避免实时调用函数的情况,他只会在最后一次scroll事件触发后调用,函数防抖其实是先初始化了一个定时器,每次事件在延迟事件类被触发时都会重置定时器,直至最后一个事件触发完。
var decounce = function(fn, delay) { let timer = null return function() { let _this = this clearTimeout(timer) // 每次调用debounce函数都会将前一次的timer清空,确保只执行一次 timer = setTimeout(() => { fn.apply(_this,args) }, delay) } }
document.addEventListener('scroll', decounce(scrollTap, 1000)); // 调用decounce函数
此时我们的函数触发就变少了。
当然,函数节流与之想类似,就是在指定的时间段内只执行一次期望函数,在我们的联想搜索时,常常会出现当前字符触发的联想字词还没来得及出现就已经触发下一个联想字词了,这里我们也需要用到防抖。