高階函數之節流與防抖

  • 節流和防抖在我們的日常代碼中經常會遇到,下面我們來認識一下節流和防抖的應用場景以及它們的定義。

定義

  • 相同點:兩者的前提都是頻繁觸發
  • 不同點:
  • 節流:是確保函數特定的時間內至多執行一次。
  • 防抖:是函數在特定的時間內不被再調用後執行。

應用場景

  • 節流:鼠標連續多次click事件,mousemove 事件,監聽滾動事件,比如是否滑到底部自動加載更多等等…
  • 防抖:輸入框搜索自動補全事件,頻繁操作點贊和取消點贊等等

防抖

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <input type="text" id="name">
    <script>
      let input = document.getElementById('name');
      function debonce(func, context, delay){
        return function(){
          let args = [].slice.call(arguments);
          //再次執行時清空定時器,確保只執行一次
          func.id && clearTimeout( func.id );
          func.id = setTimeout( function(){
            func.apply(context,args);
          },delay);
        }
      }
      let debonceAjax = debonce(ajax, null, 2000);
      input.addEventListener('keyup',function(e){
        debonceAjax(e.target.value);
      });
      function ajax(data,type){
        console.log('ajax request ' + data + ' success');
      }
    </script>
</body>
</html>

節流

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
      li {
        height: 50px;
        margin: 20px;
        background: #ccc;
      }
    </style>
</head>
<body>
    <ul id="container"></ul>
    <script>
      let container = document.getElementById('container');
      let lisHtml = '';
      for(let i=0; i<30; i++){
        lisHtml += `<li>我是第 ${i} 個數據</li>`
      }
      container.innerHTML = (lisHtml);
      let throttleAjax = throttle(ajax, 1000);
      document.addEventListener('scroll',function(){
        throttleAjax('newData');
      })
      
      function throttle(fn, delay) {
        let lastTime; 
        let timer; 
        delay || (delay = 300); // 默認間隔爲300ms
        return function() {
          let context = this;
          let args = arguments;
          let nowTime = +new Date(); // 獲取系統當前的時間
            if (lastTime && nowTime < lastTime+ delay) { // 當前距離上次執行的時間小於設置的時間間隔
                clearTimeout(timer); // 清除定時器
                timer = setTimeout(function() { // delay時間後,執行函數
                  lastTime= nowTime ;
                  fn.apply(context, args);
                }, delay);
              } else { // 當前距離上次執行的時間大於等於設置的時間,直接執行函數
                lastTime= nowTime ;
                fn.apply(context, args);
              }
          };
        }


      function ajax(data){
        console.log('這裏是最新數據'+ data)
      }
    </script>
</body>
</html>

節流防抖優化函數

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章