防抖节流笔记

防抖节流

  • 面试时,面试官问:网络环境差的情况,如何防止用户多次点击?
  • 没想过防抖节流的方法,回答完,面试官反问使用过防抖节流处理过吗???
  • 没有!!!防抖节流是啥都了解不清楚!!!

防抖与节流的原理

防抖节流是前端应用开发中常见的功能!是利用闭包,缓存延迟时间。主要应用场景就是会频繁触发的事件,如浏览器的resize(窗口大小变化)、scroll,鼠标的mousemove、mouseover,input输入框键盘事件等,不断地调用绑定在事件上的回调函数,极大的浪费资源,降低性能。需要对这类事件进行调用次数的限制,优化体验。

防抖debounce

不停触发事件,但是它一定在事件触发n秒后才执行,如果在一个事件触发的n秒内又触发了该事件,则累计时间清零,以新事件触发的时间为准,再过n秒后才执行。总之,就是 要等你触发事件完n秒内不在触发,才执行
打个比方:景区入园,规定每5秒,进入一批;

  • 来了一批人,进去,后面的人要5秒后才可以进入
  • 过了1秒又来了一批人,不能进,累计时间清零(重置定时器),还要等5秒后
  • 过了2秒又来了一批人,不能进,累计时间再清零,还要再等5秒
  • 5秒后,可以进入了 (实际等待时间:1+2+5秒)
function debounce (func, delay = 5000) { // delay = 5000设置默认值
	let timer = null
	return function () {
		if (timer) clearTimeout(timer)
		timer = setTimeout(() => {
			func.apply(this, arguments) // 直接用this,因为使用箭头函数
          	timer = null
		}, delay)
	}
}

document.querySelector('#div').onmousemove = debounce(function Fn(event){
	console.log(this)
	console.log(event)
})
  • 以上代码的逻辑就是:判断是否存在定时器,存在就清除定时器,然后重新定义一个定时器,定时器到时间再执行Fn函数
  • 代码中使用到了闭包,主要目的是为了函数执行后保留timer这个变量在局部作用域,不污染全局变量。
    问:为什么要返回一个函数?
    试了下没有返回函数的写法:删掉debounce函数中的return,把timer提到全局变量(为了保留timer)
let timer = null
function debounce(func, delay) {
	if (timer) clearTimeout(timer)
	timer = setTimeout(() => {
		func.apply(this, arguments)
		timer = null
	}, delay)
}
// document.querySelector('#div').onmousemove = debounce(function Fn(event){
// 	 console.log(this)
//	 console.log(event)
// })

// 执行代码后,看见就只执行了一次!!!
// 在debounce函数里面返回一个函数,因为onmousemove需要的是未执行的函数。 如下写法,也可让debounce函数一定时间后就执行
document.querySelector('#div').onmousemove = function Fn(event){
	debounce(() => {
		console.log(this)
		console.log(event)
	})
}

这种写法和第一个debounce函数通过闭包方式返回一个函数结果一样,推荐使用第一种,闭包写法可以避免变量的全局污染

节流throttle

防抖和节流本质上是不一样的。防抖动是将多次执行变为最后一次执行,节流是将多次执行变成每隔一段时间执行。
当触发事件的时候,设置一个定时器,再触发事件的时候,如果定时器存在,就不执行,直到定时器执行函数,清空定时器,才可以再设置下一个定时器
照样是景区入园的例子:规定每5秒进去一批

  • 来了一批人,进入
  • 过1秒来一批,需要等待4秒,进入
  • 又过1秒来一批,需要等待3秒,进入
function throttle (func, delay = 5000) {
	let timer = null
	return function () {
		if (timer) return
		timer = setTimeout(() => {
			func.apply(this, arguments)
			timer = null
		}, delay)
	}
}
document.querySelector('#div').onmousemove = throttle(function Fn(event){
	console.log(this)
	console.log(event)
})
防抖节流应用场景
防抖

适用于:连续的事件,只需要触发一次回调的场景

  • 输入框输入。只需要用户最后一次输入完后,在发送请求。(手机号、邮箱验证等输入校验)
  • 浏览器窗口大小resize。只需要窗口调整完成后,计算窗口大小。防止重复渲染。
节流

适用于:间隔一段时间执行一次回调的场景

  • 浏览器滚动加载、加载更多、滚动到底部监听
  • 搜索联想功能
  • 高频点击,表单重复提交

参考:
js防抖节流详解和应用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值