函数防抖和节流
函数防抖和函数节流:是优化高频率执行的JavaScript代码的一种手段。常用于JavaScript中的一些事件,如浏览器的resize、scroll,鼠标的mousemove、mouseover,键盘的keypress等。例如input输入框的keypress事件在触发时,会不断地调用绑定在事件上的回调函数,极大地浪费资源,降低前端性能。为了优化体验,就需要对这类事件进行调用次数的限制。
函数防抖
在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。
原始版本:
let timer // 定时器标志
// 为了方便,使用滚动事件作为代码范例
document.body.onscroll = function () {
if(timer){
// 如果定时器存则清除定时器
clearTimeout(timer);
}
// 重新设置定时器
timer = setTimeout(function () {
console.log("执行任务了")
}, delay);
}
封装版本:
function debounce(fn, delay) {
let _this = this //防止this的指向改变先存起来
let timer
return function () {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(function () {
fn.apply(_this,arguments)
}, delay);
}
}
函数节流
每隔一段时间,只执行一次函数。
原始版本:
let gapTime = delay//规定最小时间间隔
let lastTime //定义记录最后时间的变量
let nowTime //定义记录开始时间的变量
let fn = () => console.log('我执行了')
document.body.onscroll = () => {
nowTime = Date.now() //获取当前时间
//如果lastTime存在,并且时间间隔大于最小时间才会执行右边的逻辑
if (!lastTime || nowTime - lastTime > gapTime) {
fn()
lastTime = nowTime
}
})
封装版本:
function throttle(fn, gapTime) {
let lastTime
let nowTime
return function (){
nowTime = Date.now()
if (!lastTime || nowTime - lastTime > gapTime) {
fn()
lastTime = nowTime
}
}
}
常见应用场景
函数防抖的应用场景
连续的事件,只需触发一次回调的场景有:
- 搜索框搜索输入。只需用户最后一次输入完,再发送请求
- 手机号、邮箱验证输入检测
- 窗口大小Resize。只需窗口调整完成后,计算窗口大小。防止重复渲染。
函数节流的应用场景
间隔一段时间执行一次回调的场景有:
- 滚动加载,加载更多或滚到底部监听
- 谷歌搜索框,搜索联想功能
- 高频点击提交,表单重复提交
本文只是为了弄清楚函数防抖和函数节流的原理,所以只介绍了最原始的实现方法,你也可以根据需求对原始版本进一步改进、封装,从而运用到生产环境中。