去抖(debounce)和节流(throttle)都是限制函数不会在短时间内被频繁触发执行的方法。
两者的区别简单来说, 就是:去抖是频繁触发只会执行一次, 而节流则是频繁触发但是有间隔的执行
模拟一个点击事件
<div id="testDiv" onclick="testClick()">
点击
</div>
去抖:
//函数去抖
//去抖debounce: 一段时间内连续的函数调用,只允许其执行一次。原理是,维护一个定时器,只有定时器结束才可以继续触发事件
//第三个参数immediate为true时, 点击第一次的时候便立即执行, delay内的剩余次数不再触发
//第三个参数immediate为false时, delay, 频繁点击, 只会触发最后一次, 因为前几次的timer都被清掉了
var timer;
function debounce(fn, delay, immediate) {
return function() {
let _this = this;
let opt = arguments;
if(timer) {
clearTimeout(timer);
}
if(immediate) {
let call = !timer;
timer = setTimeout(function() {
timer = false;
}, delay || 300);
call && fn.apply(_this, opt);
} else {
timer = setTimeout(function() {
fn.apply(_this, opt);
}, delay || 300);
}
}
}
function print() {
console.log('hello world!');
}
function testClick() {
debounce(print, 1000, false)()
}
节流:
//函数节流
//节流throttle: 一段时间内的函数调用,保证事件一定会被执行一次。原理是判断两次执行函数的时间间隔是否大于延迟的时间。
//让连续执行的函数,变成固定时间段间断地执行
//intervalTime 间隔时间
var timer; // 定时器变量
var time = 0; //时间变量
function throttle(fn, delay, intervalTime) {
return function() {
var context = this;
var curTime = new Date(); //当前执行的时间
clearTimeout(timer);
if (!time) {
time = curTime
}
//当前执行时间距离上次执行时间 ,是否大于等于间隔时间
if(curTime - time >= intervalTime) {
time = curTime;
fn.apply(context, arguments)
} else {
timer = setTimeout(() => {
fn.apply(context, arguments)
}, delay);
}
}
}
function print() {
console.log('hello world!');
}
function testClick() {
throttle(print, 500, 1000)()
}