js防抖和节流
防抖和节流在前端性能优化中很常用,防抖和节流都是对一段时间内事件触发函数执行频率的控制;使用场景就是当频繁事件时怎样去处理函数执行。
防抖
在限定时间内,如果事件再次触发,丢弃当前已响应的函数执行,以当前事件响应函数重新计时
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| function debounce(fn, wait) { wait = wait || 200; var timer = null; return function () { if (timer) { clearTimeout(timer); } var args = arguments; var that = this; timer = setTimeout(function () { timer = null; fn.apply(that, args); }, wait) } }
|
_.debounceUnderscore.js1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| _.debounce = function(func, wait, immediate) { var timeout, result;
var later = function(context, args) { timeout = null; if (args) result = func.apply(context, args); };
var debounced = restArguments(function(args) { if (timeout) clearTimeout(timeout); if (immediate) { var callNow = !timeout; timeout = setTimeout(later, wait); if (callNow) result = func.apply(this, args); } else { timeout = _.delay(later, wait, this, args); }
return result; });
debounced.cancel = function() { clearTimeout(timeout); timeout = null; };
return debounced; };
|
节流
在限定时间内,如果事件再次触发,忽略事件响应,当到达时间后函数执行后再开始事件响应
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| function throttle(fn, wait) { wait = wait || 200; var timer = null; return function () { if (timer) { return; } var args = arguments; var that = this; timer = setTimeout(function () { fn.apply(that, args); timer = null; }, wait) } }
|
_.debounceUnderscore.js1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| _.throttle = function(func, wait, options) { var timeout, context, args, result; var previous = 0; if (!options) options = {};
var later = function() { previous = options.leading === false ? 0 : _.now(); timeout = null; result = func.apply(context, args); if (!timeout) context = args = null; };
var throttled = function() { var now = _.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); if (!timeout) context = args = null; } 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; };
|