1 函数防抖(debounce)
简单地说,就是当一个动作连续触发时,只执行最后一次
应用场景:
1)高频率的提交事件
实现方式
函数防抖在执行目标方法时,会等待一段时间。
当又执行相同方法时,若前一个定时任务未执行完,则清除之前的定时器,重新设置定时器。
function debounce(func, delay) {
var timeout;
return function(e) {
//当函数再次被触发时清除之前的定时器(也就时一直不执行相应的动作)
clearTimeout(timeout);
var context = this, args = arguments
//设置新的定时器
timeout = setTimeout(function(){
func.apply(context, args);
},delay)
};
};
当用户不触发时,动作开始执行
2 函数节流(throttle)
简单地说,就是当一个动作连续触发时,控制动作的执行周期,使其在一定的时间内执行一次
应用场景:
1)搜索框,在搜索内容时,根据输入信息定时的进行检索
2)滚动加载内容时
3)重复点击提交表单时
4)输入框输入的信息需要进行验证
5)在改变窗口大小的时候,鼠标松开后再开始计算窗口大小,避免重复渲染
6)touchmove(),mousemove(),scroll()....
节流实现方式有两种:
一 定时器实现方式
定时器的实现方式:
通过设置定时器,延时方法执行,若在延时过程中被触发,则不作任何处理
否则,执行一次,这保证了方法只在指定的时间内执行一次。
function throttle(func, wait) {
let timeout;
return function() {
let context = this;
let args = arguments;
if (!timeout) {
timeout = setTimeout(() => {
timeout = null;
func.apply(context, args)
}, wait)
}
}
}
二 时间戳实现方式
实现原理:
通过比对上一次执行时间与本次执行时间的时间差与间隔时间的大小关系,
来判断是否执行函数。
若时间差大于间隔时间,则立刻执行一次函数。并更新上一次执行时间。
function throttle(func, wait) {
let previous = 0;
return function() {
let now = Date.now();
let context = this;
let args = arguments;
if (now - previous > wait) {
func.apply(context, args);
previous = now;
}
}
}
体验一下正常情况,防抖,节流情况下的onmousemove函数的执行情况
戳我体验
3 两者异同点
相同点:
1)都可以通过使用 setTimeout 实现。
2)目的都是,降低回调执行频率,节省计算资源。
不同点:
1)函数防抖,在一段连续操作结束后,处理回调,利用 clearTimeout 和 setTimeout 实现。
函数节流,在一段连续操作中,每一段时间只执行一次,在频率较高的事件中使用来提高性能。
2)函数防抖关注一定时间连续触发,只在最后执行一次
而函数节流侧重于一段时间内只执行一次。