1、throttle 节流:drag改变浏览器大小,触发onresize函数,实现拖动每过1秒输出一次,不足1秒,1秒后输出一次。多用于高频操作,如抢票、抢购等,无论点击多少次,只固定间隔执行一次,以减轻压力。
原理: 设置canRun作为是否执行的标志。每次触发onresize,都判断canRun的值(true执行,false不执行)。第一次应该执行,所以设置canRun初始值为true。当第一次执行后,设置canRun为false(防止下次执行),并设置计时器,以恢复canRun的值。
var canRun = true;
window.onresize = function() {
if (!canRun){
return;
}
canRun = false;
setTimeout(function() {
console.log('节流了');
canRun = true;
}, 1000);
}
好,原理有了,接下来我们封装一个随处可用的函数,"window"只是为了理解。可以删掉:
window.canRun = true;
window.throttle = function(callback, time) {
if (!window.canRun) {
return;
}
window.canRun = false;
setTimeout(function() {
callback();
window.canRun = true;
}, time);
}
// 这样使用:
window.onresize = function() {
window.throttle(function() {
console.log('防抖成功'); // 业务代码
}, 1000);
}
2、debounce防抖:drag改变浏览器大小,触发onresize函数,实现拖动停顿1秒输出。多用于输入框,当某一次输入后停顿满n秒才会去触发远程搜索。
原理:timer作为定时器,每次触发onresize事件,都清一下定时器(之前未执行的drag方法就不会再执行),新的定时器在1秒后执行方法,那么如果下次drag在1秒内,这次赋值的定时器又会被清掉(搜索方法不会执行),直到下次drag相对于这次drag间隔时间大于1秒(定时器可能没那么准)再执行一次方法onresize。
var timer = false;
window.onresize = function() {
console.log('1');
clearTimeout(timer);
timer = setTimeout(function() {
console.log('防抖动');
}, 1000);
}
同样,封装起来使用:
timer = false;
debounce = function(callback, time) {
clearTimeout(timer);
timer = setTimeout(callback, time);
}
onresize = function() {
debounce(() => {console.log('不抖了');}, 1000);
}