js的防抖和节流

防抖和节流

共同点:都是为了限制函数的执行次数,避免短时间内不必要的多次函数执行,导致响应速度跟不上触发频率,引起页面卡顿

防抖(debounce)

基本思想:高频率触发的事件,在触发事件停下的一段时间后执行一次函数,若在这段时间内事件再次触发,则重新开始计算周期,其特点就是事件连续触发时只执行一次函数,执行完函数后再次触发事件,开启新的周期
延迟debounce:周期结束时执行动作
前缘debounce:周期开始时执行动作
延迟debounce使用场景:输入框输入时进行某些操作,比如调接口、处理数据格式、自动补全关键字等,都可以在暂停连续输入的时候才操作
下面是debounce代码,immediate控制是前缘还是延迟debounce

function debounce(fn, delay, immediate) {
	let timer, timestamp = 0, args, context
	
	let run = function() {
		timer = setTimeout(function() {
			// 改变this指向调用debounce的上下文环境
			if(!immediate) {
				fn.apply(context, args)
			}
		}, delay)
	}
	
	return function() {
		args = arguments
		context = this
		// 获取当前时间戳
		let now = new Date().getTime()
		if(now - timestamp < delay) {
			// 周期内触发事件,重置定时器,重新设置时间周期
			clearTimeout(timer)
			run()
		} else {
			if(immediate) {
				fn.apply(context, args)
			}
			// 两次触发事件的时间间隔大于时间周期,则开启新的时间周期
			run()
		}
		timestamp = now
	}
}

function handle() {
 	console.log('执行事件')
}

window.addEventListener('scroll', debounce(handle, 1000))

简化代码

function debounce(fn, delay) {
	let timer = null
	return function() {
		if(timer) {
			// 触发事件,清除定时器,重新计时
			clearTimeout(timer)
			timer = null
		}
		timer = setTimeout(() => {
			fn.apply(this, arguments)
		}, delay)
	}
}

优化代码,减少设定定时器的次数,在执行定时器的代码过程中判断起始时间的变化,若变化了则需要设置延时定时器,延时定时器的时间长度等于delay - now - startTimestamp, 也就是整个过程中必须保证事件触发停止一段时间(delay)后才执行函数

function debounce(fn, delay, immediate) {
	let timer, startTimestamp, args, context
	
	let run = function(wait) {
		timer = setTimeout(() => {
			const now = new Date().getTime()
			const interval = now - startTimestamp
			if(interval < wait) {
				// 如果周期内事件触发,开始时间戳会增加,则差值必然小于wait
				startTimestamp = now
				run(delay - interval)
			} else {
				if(!immediate) {
					fn.apply(context, args)
				}
				clearTimeout(timer)
				timer = null
			}
		}, wait)
	}
	
	return function() {
		args = arguments
		context = this
		// 事件触发,则更新起始时间
		startTimestamp = new Date().getTime()
		
		if(!timer) {
			if(immediate) {
				fn.apply(context, args)
			}
			run(delay)
		}
	}
}

节流

基本思想:高频率触发的事件,周期时间内只执行一次动作,稀释了执行动作的频率
特点:事件连续触发的时候,只在到达时间周期才执行动作,响应平滑,周期结束后,事件触发再次开始新的时间周期
使用场景:监听滚动条滚动事件,滚动时根据滚动的高度给元素增加某些样式或动画效果,页面滚动到底部加载更多

// immediate开启前缘
function throttle(fn, delay, immediate) {
	let timer = null
	
	return function() {
		if(timer) return
		if(immediate) fn.apply(this, arguments)
		timer = setTimeout(() => {
			if(!immediate) {
				fn.apply(this, arguments)
			}
			clearTimeout(timer)
         	timer = null
		}, delay)
	}
}

function handle() {
	console.log('执行事件')
}

window.addEventListener('scroll', throttle(handle, 1000))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值