淺談JS函數節流及應用場景


說完防抖,下面我們講講節流,規矩就不說了,先上代碼:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>節流</title>
</head>
<body>

  <button id="throttle">點我節流!</button>

  <script>
    window.onload = function() {
      // 1、獲取按鈕,綁定點擊事件
      var myThrottle = document.getElementById("throttle");
      myThrottle.addEventListener("click", throttle(sayThrottle));
    }

    // 2、節流函數體
    function throttle(fn) {
      // 4、通過閉包保存一個標記
      let canRun = true;
      return function() {
        // 5、在函數開頭判斷標志是否為 true,不為 true 則中斷函數
        if(!canRun) {
          return;
        }
        // 6、將 canRun 設置為 false,防止執行之前再被執行
        canRun = false;
        // 7、定時器
        setTimeout( () => {
          fn.call(this, arguments);
          // 8、執行完事件(比如調用完接口)之后,重新將這個標志設置為 true
          canRun = true;
        }, 1000);
      };
    }

    // 3、需要節流的事件
    function sayThrottle() {
      console.log("節流成功!");
    }

  </script>
</body>
</html>

很好,看完代碼的小伙伴應該大致清楚是怎么回事了,下面我們看 GIF 實現:

 

 

看完代碼和 GIF 實現,我們可以明白,節流即是:

  • 節流指定時間間隔內只會執行一次任務。

那么,節流在工作中的應用?

  1. 懶加載要監聽計算滾動條的位置,使用節流按一定時間的頻率獲取。
  2. 用戶點擊提交按鈕,假設我們知道接口大致的返回時間的情況下,我們使用節流,只允許一定時間內點擊一次。

這樣,在某些特定的工作場景,我們就可以使用防抖與節流來減少不必要的損耗。

那么問題來了,假設面試官聽到你這句話,是不是會接着問一句:“為什么說上面的場景不節制會造成過多損耗呢?”

OK,這就涉及到瀏覽器渲染頁面的機制了……



 

案例2:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>demo</title>
</head>
<body>
    <input type="text" name="search">

    <script type="text/javascript">
        var searchInput = document.querySelector('input[name="search"]');
        /*綁定事件*/
        searchInput.addEventListener('keyup',throttle(getInputValue),false);
        /* 節流函數 */
        function throttle(fn){
            /*通過閉包保存一個標記*/
            let timer = true;
            return function(){
                /*在函數開頭判斷標志是否為 true,不為 true 則中斷函數*/
                if(!timer){
                    return;
                }
                /*將 timer 設置為 false,防止執行之前再被執行*/
                timer = false;
                /* 定時器 */
                setTimeout(()=>{
                    fn.call(this,arguments)
                    /*執行完事件(比如調用完接口)之后,重新將這個標志設置為 true*/
                    timer = true;
                },1000)
            }
        }
        /* 調用獲取輸入值 */
        function getInputValue(){
            console.dir(this.value)
        }
    </script>
</body>
</html>

 

 

 

 

.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM