前言
防抖节流作为前端面试经典手撕代码题,掌握防抖和节流是一个前端开发人员工程能力的体现,不会封装防抖和节流?一起来学习吧~🙆♂️
防抖(debounce)
基本概念
在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。
举个🌰子
我们在搜索框输入关键词进行搜索时,就会发送ajax请求,然后展示在列表,这是一个很常见的场景,接下来我们来模拟一下:
<span>防抖案例</span> <input type="text"> 复制代码
const input = document.querySelector('input') input.addEventListener('keyup',function(){ // 模拟ajax请求 console.log(input.value); }) 复制代码
我们会发现每次只要按下键盘都会发送ajax请求,然而这是非常浪费资源的,我们应该在用户输入完字符后一段时间再发送ajax请求,我们来优化一下~
const input = document.querySelector('input') let timer = null input.addEventListener('keyup',function(){ if(timer) { clearTimeout(timer) } timer = setTimeout(()=>{ // 模拟ajax请求 console.log(input.value); // 清空定时器 timer = null },500) }) 复制代码
我们通过演示可以发现,当你在频繁的输入时,并不会发送请求,只有当你在500ms内没有输入时,才会执行函数。如果停止输入但是在指定间隔内又输入,会重新触发计时。这样我们的防抖功能就实现啦~
防抖就好像是英雄释放技能时的读条,技能读条没读完再次使用该技能就会重新读条。
封装防抖函数
上面我们只对该输入框做了防抖,如果有多个输入框需要做防抖,我们不应该把这个防抖功能再实现一次,应该封装一个防抖函数,该使用防抖的时候调用它即可,我们来尝试吧~
// 封装防抖函数 function debounce(fn,delay = 500){ let timer = null return function(){ if(timer) { clearTimeout(timer) } timer = setTimeout(()=>{ fn.apply(this,arguments) timer = null },delay) } } // 使用 input.addEventListener('keyup',debounce(function() { console.log(input.value); },500)) 复制代码
节流(throttle)
基本概念
规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。
举个🌰子
拖拽一个元素时,要随时拿到该元素被拖拽的位置,如果没有节流,只要该元素移动1丢丢,哪怕是1px,都会获取当前拖拽的位置,这是非常消耗性能的,容易造成卡顿。
那我们就来优化一下,使用节流,每500ms获取当前元素的位置,来看代码:
const div1 = document.querySelector('div') let timer = null div1.addEventListener('drag',function(e){ if(timer) { return } timer = setTimeout(()=>{ console.log(e.offsetX,e.offsetY); timer = null },500) }) 复制代码
这样我们的节流操作就做好啦,来看效果~
节流就好像是你在玩吃鸡时,即使你猛戳开火键,子弹也只会以预定的速度射出,这么样是不是很好理解。
封装节流函数
// 封装节流 function throttle(fn,delay = 500) { let timer = null return function() { if(timer) { return } timer = setTimeout(()=>{ fn.apply(this,arguments) timer = null },delay) } } // 使用 div1.addEventListener('drag',throttle(function(e){ console.log(e.offsetX,e.offsetY); },500)) 复制代码
最后
⚽本文介绍了性能优化中的防抖节流的概念以及如何使用~
⚾如果这篇文章对你有帮助的话,麻烦点赞收藏哟~