在前端开发中会遇到一些频繁的事件触发,比如:

  1. window 的 resize、scroll
  2. mousedown、mousemove
  3. keyup、keydown
    ……

为此,我们举个示例代码来了解事件如何频繁的触发:

我们写个 index.html 文件:

  1. <!DOCTYPE html>
  2. <html lang="zh-cmn-Hans">
  3. <head>
  4. <meta charset="utf-8">
  5. <meta http-equiv="x-ua-compatible" content="IE=edge, chrome=1">
  6. <title>debounce</title>
  7. <style>
  8. #container {
  9. width: 100%;
  10. height: 200px;
  11. line-height: 200px;
  12. text-align: center;
  13. color: #fff;
  14. background-color: #444;
  15. font-size: 30px;
  16. }
  17. </style>
  18. </head>
  19. <body>
  20. <div id="container"></div>
  21. <script>
  22. var count = 1;
  23. var container = document.getElementById('container');
  24. function getUserAction() {
  25. container.innerHTML = count++;
  26. };
  27. container.onmousemove = getUserAction;
  28. </script>
  29. </body>
  30. </html>

image.png

从左边滑到右边就触发了 100多次 getUserAction 函数!

因为这个例子很简单,所以浏览器完全反应的过来,可是如果是复杂的回调函数或是 ajax 请求呢?假设 1 秒触发了 60 次,因为大多数设备是60hz刷新率,所以每个回调就必须在 1000 / 60 = 16.67ms 内完成,否则就会有卡顿出现。

为了解决这个问题,一般有两种解决方案:

  1. debounce 防抖
  2. throttle 节流

debounce 防抖

防抖的原理就是:你尽管触发事件,但是我一定在事件触发 n 秒后才执行,如果你在一个事件触发的 n 秒内又触发了这个事件,那我就以新的事件的时间为准,n 秒后才执行,总之,就是要等你触发完事件 n 秒内不再触发事件,我才执行,真是任性呐!

  1. container.onmousemove = debounce(getUserAction, 1000);
  2. function debounce(func, wait) {
  3. var timeout;
  4. return function () {
  5. clearTimeout(timeout)
  6. timeout = setTimeout(func, wait);
  7. }
  8. }


https://github.com/mqyqingfeng/Blog/issues/22