防抖debounce: 多次高频触发某一个事件,小于delay定时器执行间隔则重新计时。
源码:
function debounce(func,delay){
var timeout;
return function(e){
clearTimeout(timeout); //小于delay定时器执行间隔则重新计时
var context = this,args=arguments;
timeout = setTimeout(function(){
func.apply(context,args);
},delay)
}
}
// 定义校验器
var validate = debounce(function(e){
console.log('change', e.target.value, new Date() - 0)
},380)
// 绑定监听
document.querySelector('input').addEventListener('input', validate)
场景: input输入搜索事件,提交按钮的点击事件
节流throtte:多次高频触发某一个事件,限制delay期间必须执行一次事件,没达到delay的事件也算.
源码:
function throttle(fn,threshhold){
var timeout;
var start = new Date;
var threshhold = threshhold || 160;
return function(){
var context = this,args=arguments,curr=new Date() - 0;
clearTimeout(timeout) // 关闭定时器
if(cur - start >= threshhold){ //大于时间间隔,直接执行
fn.apply(context,args);
start = cur;
}else{
timeout = setTimeout(function(){ //小于时间间隔,setTimeOut设置时间间隔执行
fn.apply(context,args)
},threshhold)
}
}
}
var mousemove = throttle(function(e) {
console.log(e.pageX, e.pageY)
});
// 绑定监听
document.querySelector("#panel").addEventListener('mousemove', mousemove);
场景:如resize, touchmove, mousemove, scroll。throttle 会强制函数以固定的速率执行。因此这个方法比较适合应用于动画相关的场景。
总结: debounce多次触发,以最后一次触发为准;throttle多次触发以固定间隔触发事件。 debounce限制多长时间才能执行一次,throttle限制多长时间必须执行一次,一个限制上限、一个限制下限。其实这两个方法可以合二为一的。