JS 之防抖(debounce)和 节流(throttle)

351 阅读1分钟

防抖(debounce)

日常场景,比如resize, 搜索框输入,手机号邮箱校验等,需要等到最后输入完成在执行;
概念: n秒后触发,如果在n秒中又触发新的事件,则清除,重新计时;

<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <input type="text" id="txt">
  <div id="dv"></div>
  <script>
     txt.addEventListener('input', debounce(function(e){
        let val = e.target.value;
        document.getElementById('dv').innerText = val;
     }, 500))
  </script>
</body>
</html>
// debounce n秒后执行回调函数,如果n秒内又触发,则重新计时
function debounce(fn, delay) {
  let timer;  // 闭包
  return function(){
    if(timer) {
      clearTimeout(timer); // 如果n秒内又触发,则重新计时
    }
    timer = setTimeout(_ => {
      fn.apply(this, arguments) // apply 改变this指向, 传参
    }, delay)
  }
}

节流(throttle)

日常场景,拖动,用户连续点击,滚动加载等;
概念: 按照一定的频率触发事件;

<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .drag {
      width: 100%;
      height: 100px;
      background: pink;
      position: relative;
    }
  </style>
</head>
<body>
  <div class="drag" draggable="true" id="drag">sadads</div>
  <script>
    drag.addEventListener('mousemove', throttle(function(e){
      console.log(999, e, this)
    }, 1000))
  </script>
</body>
</html>
// throttle 按照一定的频率触发
function throttle(fn, time) {
  let timer;
  return () => {
    if(timer) {
      return;
    }
    timer = setTimeout(_ => {
      timer = null;
      fn.apply(this, arguments)
    }, time)
  }
}