概念

在前端开发的过程中,我们经常会需要绑定一些持续触发的事件,如滚动、输入等等,但有些时候我们并不希望在事件持续触发的过程中那么频繁地去执行函数,防抖和节流是比较好的解决方案。
(1)所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。使用场景:注册的时候检查用户名是否已经被注册.
(2)所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率。使用场景:监听滚动条是否到了顶部或底部.

防抖和节流的区别

函数防抖和节流区别在于,当事件持续被触发,如果触发时间间隔短于规定的等待时间(n秒),那么

  • 函数防抖的情况下,函数将一直推迟执行,造成不会被执行的效果;
  • 函数节流的情况下,函数将每个 n 秒执行一次。

防抖

  1. <!DOCTYPE html>
  2. <head>
  3. <meta charset="UTF-8">
  4. </head>
  5. <body>
  6. 用户名: <input onblur="checkUsername" placeholder="请输入用户名" id="username" />
  7. <script>
  8. // 1.定义一个timer定时器
  9. var timer;
  10. // 2.获取input节点
  11. var $username = document.getElementById('username');
  12. // 3.绑定input事件
  13. $username.addEventListener('input', function() {
  14. // 4.每次输入都会清除定时器,所以连续输入,定时器是不会触发,触发,除非停止输入超过1秒定时器才会执行
  15. clearTimeout(timer);
  16. timer = setTimeout(function() {
  17. console.log('发请求到后台,检查用户是否已注册');
  18. }, 1000)
  19. }, false)
  20. </script>
  21. </body>

封装函数

  1. // 上面例子中的函数,一般单独写出来,给它命名为debounce
  2. var $username = document.getElementById("username");
  3. $username.addEventListener("input", debounce, false);
  4. var timer;
  5. function debounce() {
  6. clearTimeout(timer);
  7. timer = setTimeout(function() {
  8. console.log("发请求到后台,检查用户是否已注册");
  9. }, 1000);
  10. }

节流

  1. <!DOCTYPE html>
  2. <head>
  3. <meta charset="UTF-8">
  4. <style>
  5. p {height: 300px}
  6. </style>
  7. </head>
  8. <body>
  9. <div id="box">
  10. <p>ppppppppppppppppp</p>
  11. <p>ppppppppppppppppp</p>
  12. <p>ppppppppppppppppp</p>
  13. <p>ppppppppppppppppp</p>
  14. <p>ppppppppppppppppp</p>
  15. <p>ppppppppppppppppp</p>
  16. <p>ppppppppppppppppp</p>
  17. <p>ppppppppppppppppp</p>
  18. <p>ppppppppppppppppp</p>
  19. <p>ppppppppppppppppp</p>
  20. </div>
  21. <script>
  22. var $username = document.getElementById('username');
  23. window.onscroll = throttle;
  24. // 1.上一次事件触发的时间
  25. let oldTime = Date.now(); // 10:00:00
  26. function throttle() {
  27. // 现在触发的时间
  28. let newTime = Date.now();
  29. // 现在点击的时间跟上一次点击的时间如果超过了一秒,执行回调
  30. if (newTime - oldTime >= 1000) {
  31. // 在这里执行我们想做的事情
  32. console.log('想干嘛干嘛');
  33. // 从新计时,这次点击的时间成为下一次点击时间的起点
  34. oldTime = newTime;
  35. }
  36. }
  37. </script>
  38. </body>