[关闭]
@hotjp 2017-05-08T08:43:05.000000Z 字数 2091 阅读 1523

函数防抖 函数节流

培训


函数防抖(debounce

定义:

连续的调用,停止t后才会执行该动作,若在这t内又调用此动作则将重新计算t

场景案例:

监听 resize 事件,每缩小(或者放大)一次浏览器,实际上会触发多次,用户玩够了再执行

解决方案:

  1. $(function() {
  2. var foo = debounce(resizeBox, 1000);
  3. $(window).on('load resize', foo);
  4. });
  5. function resizeBox() {
  6. var fullWidth = $('body').width(),
  7. maxWidth = 800;
  8. if (fullWidth <= maxWidth) {
  9. $('.full').width(fullWidth);
  10. } else {
  11. $('.full').width(maxWidth);
  12. }
  13. }

场景案例:

文本输入的验证(连续输入文字后发送 AJAX 请求进行验证,验证最后一次就好)

解决方案:

  1. $(function() {
  2. var foo = debounce(checkInput, 1000);
  3. $('.input').on('keyup', function() {
  4. foo();
  5. });
  6. });
  7. function checkInput() {
  8. // 替换为异步请求,可减少请求次数
  9. $('.type').text($('.input').val());
  10. }

函数节流(throttle

定义:

一个不间断的调用,每隔t,执行一次

场景案例:

监听 resize 事件,每缩小(或者放大)一次浏览器,实际上会触发多次,周期性更新

解决方案:

  1. $(function() {
  2. var foo = throttle(resizeBox, 1000);
  3. $(window).on('load resize', foo);
  4. });
  5. function resizeBox() {
  6. var fullWidth = $('body').width(),
  7. maxWidth = 800;
  8. if (fullWidth <= maxWidth) {
  9. $('.full').width(fullWidth);
  10. } else {
  11. $('.full').width(maxWidth);
  12. }
  13. }

场景案例:

文本输入的验证(连续输入文字后发送 AJAX 请求进行验证,周期性验证)

解决方案:

  1. $(function() {
  2. var foo = throttle(checkInput, 1000);
  3. $('.input').on('keyup', function() {
  4. foo();
  5. });
  6. });
  7. function checkInput() {
  8. // 替换为异步请求,可减少请求次数
  9. $('.type').text($('.input').val());
  10. }

相关资料:
函数节流(throttle)与函数去抖(debounce)

函数节流与去抖的可视化

  1. /*
  2. * 频率控制 返回函数连续调用时,fn 执行频率限定为每多少时间执行一次
  3. * @param fn {function} 需要调用的函数
  4. * @param delay {number} 延迟时间,单位毫秒
  5. * @param immediate {bool} 给 immediate参数传递false 绑定的函数先执行,而不是delay后后执行。
  6. * @param debounce {bool} 是否防抖动
  7. * @return {function}实际调用函数
  8. */
  9. var throttle = function(fn, delay, immediate, debounce) {
  10. var curr = +new Date(), //当前时间
  11. last_call = 0,
  12. last_exec = 0,
  13. timer = null,
  14. diff, //时间差
  15. context, //上下文
  16. args,
  17. exec = function() {
  18. last_exec = curr;
  19. fn.apply(context, args);
  20. };
  21. return function() {
  22. curr = +new Date();
  23. context = this,
  24. args = arguments,
  25. diff = curr - (debounce ? last_call : last_exec) - delay;
  26. clearTimeout(timer);
  27. if (debounce) {
  28. if (immediate) {
  29. timer = setTimeout(exec, delay);
  30. } else if (diff >= 0) {
  31. exec();
  32. }
  33. } else {
  34. if (diff >= 0) {
  35. exec();
  36. } else if (immediate) {
  37. timer = setTimeout(exec, -diff);
  38. }
  39. }
  40. last_call = curr;
  41. };
  42. };
  43. /*
  44. * 空闲控制 返回函数连续调用时,空闲时间必须大于或等于 delay,fn 才会执行
  45. * @param fn {function} 要调用的函数
  46. * @param delay {number} 空闲时间
  47. * @param immediate {bool} 给 immediate参数传递false 绑定的函数先执行,而不是delay后后执行。
  48. * @return {function}实际调用函数
  49. */
  50. var debounce = function(fn, delay, immediate) {
  51. return throttle(fn, delay, immediate, true);
  52. };
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注