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);}