前言什么是防抖?什么是节流?它们之间有什么区别?你能给个例子吗?你在面试中被问过这些问题吗?网上也有很多文章进行了解释,但大多是因为太长或者描述不清楚,难以理解。因此,我结合实际案例与大家分享。它很短,可以在几分钟内阅读。如果有什么不明白的地方欢迎在下方留言讨论。介绍在网页运行的某些场景下,会不断触发一些事件。比如scroll事件,并不是我们想象的那样,滚动的时候触发一次。相反,它将被多次触发。由于过于频繁的DOM操作和资源加载,会严重影响网页的性能,甚至会导致浏览器崩溃。常见应用场景最常见的场景是滚动事件。如下。当我们给窗口添加滚动事件监听器,然后每次滚动时触发监听器的回调函数。函数printScroll(){varscrollTop=document.body.scrollTop||文档.documentElement.scrollTop; console.log('滚动条当前位置:'+scrollTop);}window.addEventListener('scroll',printScroll)但是在运行时,我们发现滚动会触发多个回调函数,打印出来的结果如下:但是在实际开发中,我们并不需要这么高频的回调。毕竟浏览器的性能是有限的,不应该浪费在这里。那么如何优化这种情况。debounce的意思是:事件触发后,延迟n秒后执行回调。如果在这n秒内再次触发,则重新开始计时。具体实现:原理是使用闭包。//防抖功能(简化版)functiondebounce(fn,delay){lettimer=null//借助闭包returnfunction(){//每次执行前清空定时器,保证fn函数在延迟时间不强制执行。timer&&clearTimeout(timer)timer=setTimeout(fn,delay)}}//原始函数consthandlerScroll=function(){varscrollTop=document.body.scrollTop||document.documentElement.scrollTop; console.log('当前滚动条位置:'+scrollTop);}//结合两个函数实现滚动防抖constscrollHandler=debounce(handlerScroll,1000)window.addEventListener('scroll',scrollHandler)//注意:上面的代码可以复制到如果此时直接在控制台测试,会发现直到停止滚动1后才会打印滚动条的位置第二。注意:在实际开发中,需要使用apply来获取函数作用域和变量fn.apply(context,args)。在实际开发中,还有很多场景需要进行防抖处理,比如resize事件、scroll事件、input事件、拖动事件等,除了这些,还有很多情况需要我们结合实际发展。Throttle(节流阀),顾名思义,就是每n秒只执行一次回调函数。如果该函数在单位时间内被触发多次,则只会生效一次。//节流函数functionthrottle(fn,delay){lettimer=null;//定义一个定时器returnfunction(){letcontext=this;让args=参数;if(!timer){timer=setTimeout(function(){fn.apply(context,args);timer=null;},delay);}}}//原函数constscrollEvent=function(){ console.log('当前时间戳:'+newDate().getTime());}//结合两个函数实现节流和反shakeconstscrollHandler=throttle(scrollEvent,1000)//滚动事件window.addEventListener('scroll',scrollHandler);//注:以上代码可以复制到控制台直接测试连续滚动5s的实际效果:由于setTimeout函数的时间参数错误(或者函数本身执行所需的时间),打印结果的后三位可能不是预期值。除了使用定时器,节流函数还可以使用时间戳。当前时间是和之前时间对比的,这里就不多说了。总结总结一下,防抖就是事件停止触发,在指定时间后执行一次,而函数节流是在指定的单位时间间隔执行一次。防抖和节流可以有效减少浏览器引擎的损耗,防止页面拥塞和卡顿。作为一个大前端开发者,是应该掌握的技能。你在面试中被问了哪些问题?欢迎在下方留言讨论。如果您发现文章中有任何错误,请指出。如果觉得有帮助,请点赞关注支持,万分感谢!作者:tager链接:https://juejin.cn/post/7020955167419793444说明:稀土掘金同步更新版权归作者所有。商业转载请联系作者授权,非商业转载请注明出处。
