鼠标移动事件onmousemove, 滚动滚动条事件onscroll,窗口大小改变事件onresize,瞬间的操作都会导致这些事件会被高频触发。 如果事件的回调函数较为复杂,就会导致响应跟不上触发,出现页面卡顿,假死现象。 在实时检查输入时,如果我们绑定onkeyup事件发请求去服务端检查,用户输入过程中,事件的触发频率也会很高,会导致大量的请求发出,响应速度会大大跟不上触发。
一、debounce 防抖。
防抖策略是当事件被触发时,设定一个周期延迟动作,若期间又被触发,则重新设定周期,直到周期结束,执行动作。
js实现debounce
function debounce(fun, wait, immediate){
let timeout, result
var debound = function(){
var that = this
var arg = arguments
if(timeout) clearTimeout(timeout)
var later = function(){
timeout = null;
if(!immediate) result = fun.apply(that, arg)
}
if(!timeout && immediate){
result = fun.apply(that, arg)
}
timeout = setTimeout(later, wait)
return result
}
debound.cancle = function(){
clearTimeout(timeout)
timeout = null;
}
return debound
}
二、throttle 节流
节流的策略是,固定周期内,只执行一次动作,若有新事件触发,不执行。周期结束后,又有事件触发,开始新的周期。 节流策略也分前缘和延迟两种。与debounce类似,延迟是指 周期结束后执行动作,前缘是指执行动作后再开始周期
js实现throllte
function throttle(func, wait, options) {
var timeout, context, args, result;
var previous = 0;
if (!options) options = {};
var later = function() {
previous = options.leading === false? 0: Date.now();
timeout = null;
result = func.apply(context, args);
};
var throttled = function() {
var now = Date.now();
if (!previous && options.leading === false) previous = now;
var remaining = wait - (now - previous);
context = this;
args = arguments;
if (remaining <= 0 || remaining > wait) {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
previous = now;
result = func.apply(context, args);
} else if (!timeout && options.trailing !== false) {
timeout = setTimeout(later, remaining);
}
return result;
}
throttled.cancel = function() {
clearTimeout(timeout);
previous = 0;
timeout = context = args = null;
};
return throttled;
}