防抖(debounce)
在写前端脚本的时候,有时候会某一时间短时间内触发多次事件,例如 mouseover,resize,scroll 函数,如果在这些回调执行复杂的操作,那么会导致页面卡顿,所以必须采取一些措施,我们想要的是在某一连续操作的时间内,不触发操作,直到结束符合条件的指定时间后才执行,那么就可以用防抖(debounce)函数
/** * 防抖函数 * @param func 执行函数 * @param wait 多久执行一次 * @param immediate 是否立即执行 * @returns {Function} 返回防抖函数 */function debounce(func, wait, immediate) { var timeout; return function () { var context = this, args = arguments; var later = function () { timeout = null; if (!immediate) func.apply(context, args); }; var callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(later, wait); if (callNow) func.apply(context, args); };}// 使用方法var myEfficientFn = debounce(function () { // 250ms执行一次}, 250);window.addEventListener('resize', myEfficientFn);
节流(throttle)
节流就是时间间隔内只触发一次,那么实现的方法就是在防抖的基础上加个时间间隔的判断
/** * 节流函数,在连续触发的函数内控制间隔时间内执行函数 * @param func 需要执行的函数 * @param wait 间隔内执行一次 * @param immediate 是否立刻触发 * @returns {Function} 防抖函数 */function debounce(func, wait, immediate) { var timeout; return function () { var context = this, args = arguments; var later = function () { timeout = null; if (!immediate) func.apply(context, args); }; var callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(later, wait); if (callNow) func.apply(context, args); };}// 使用var myEfficientFn = debounce(function () { // 操作函数}, 250);window.addEventListener('resize', myEfficientFn);
最明了的效果可以看下面,在蓝色区域来回移动,看触发的次数
目前有第三方实现的库有:
1. jquery $.throttle和$.debounce
2. lodash _.throttle和``_.debounce
.
3. unserscore _.throttle
和_.debounce
.
参考资料:http://drupalmotion.com/article/debounce-and-throttle-visual-explanation