1. <!DOCTYPE html>
    2. <html>
    3. <head>
    4. <meta charset="UTF-8">
    5. <title>函数的防抖和节流</title>
    6. <!-- IMPORT CSS -->
    7. <link rel="stylesheet" href="css/reset.min.css">
    8. <style>
    9. html,
    10. body {
    11. height: 500%;
    12. background: -webkit-linear-gradient(top left, lightblue, lightgreen, lightyellow, orange);
    13. }
    14. </style>
    15. </head>
    16. <body>
    17. <script src="node_modules/underscore/underscore.js"></script>
    18. <script>
    19. /*
    20. * https://underscorejs.org/ JS类库(提供很多项目中需要经常使用的方法)
    21. *
    22. * 函数的防抖(debounce):不是某个事件触发就去执行函数,而是在指定的时间间隔内,执行一次,减少函
    23. 数执行的次数
    24. *
    25. * 函数的节流(throttle):为了缩减执行的频率,但不像防抖一样,一定时间内只能执行一次,而是一定时
    26. 间内能执行多次
    27. */
    28. /*
    29. * debounce:函数防抖
    30. * @params
    31. * func:要执行的函数
    32. * wait:间隔等待时间
    33. * immediate:在开始边界还是结束边界触发执行(TRUE=>在开始边界)
    34. * @return
    35. * 可被调用的函数
    36. */
    37. function debounce(func, wait, immediate) {
    38. let result = null,
    39. timeout = null;
    40. return function (...args) {
    41. let context = this,
    42. now = immediate && !timeout;
    43. clearTimeout(timeout); // 重要:在设置新的定时器之前,我们要把之前设置的定时器都干掉,因为防抖的目的是等待时间内,只执行一次
    44. timeout = setTimeout(() => {
    45. timeout = null;
    46. if (!immediate) result = func.call(context, ...args);
    47. }, wait);
    48. if (now) result = func.call(context, ...args);
    49. return result;
    50. }
    51. }
    52. /*
    53. * throttle:函数节流是为了缩减执行频率,当达到了一定的时间间隔就会执行一次
    54. * @params
    55. * func:需要执行的函数
    56. * wait:设置的间隔时间
    57. * @return
    58. * 返回可被调用的函数
    59. */
    60. let throttle = function (func, wait) {
    61. let timeout = null,
    62. result = null,
    63. previous = 0; // 上次执行时间点
    64. return function (...args) {
    65. let now = new Date,
    66. context = this;
    67. // remaining 小于等于0,表示上次执行至此所间隔时间已经超过一个时间间隔
    68. let remaining = wait - (now - previous);
    69. if (remaining <= 0) {
    70. clearTimeout(timeout);
    71. previous = now;
    72. timeout = null;
    73. result = func.apply(context, args);
    74. } else if (!timeout) {
    75. timeout = setTimeout(() => {
    76. previous = new Date;
    77. timeout = null;
    78. result = func.apply(context, args);
    79. }, remaining);
    80. }
    81. return result;
    82. };
    83. };
    84. let count = 0;
    85. function fn() {
    86. console.log(++count);
    87. }
    88. let lazyFn = _.throttle(fn, 1000);
    89. window.onscroll = lazyFn;
    90. </script>
    91. </body>
    92. </html>