前端優化 防抖與節流


事件優化

防抖與節流

防抖:

所謂防抖,就是把觸發非常頻繁的事件合並成一次去執行。即在指定時間內只執行一次回調函數,如果在指定的時間內又觸發了該事件,則回調函數的執行時間會基於此刻重新開始計算。

指觸發事件后在n秒內只執行一次,若在n秒內再次觸發則重新計算

節流:

所謂節流,是指頻繁觸發事件時,只會在指定的事件段內執行事件回調,即觸發事件間隔大於等於指定的事件才會執行回調函數。

連續發生的事件在n秒內只執行一次函數

為什么要防抖或節流
  • 及時查詢時,減少服務器壓力。
  • 頻繁執行DOM操作、資源加載等重行為,導致UI停頓甚至瀏覽器崩潰

需求是以一定的頻率執行后續的處理。

實現

防抖

只要觸發,就會清除上一個計時器,又注冊新的一個計時器。直到停止觸發wait時間后,才會執行回調函數。

不斷觸發事件,就會不斷重復這個過程,達到防止目標函數過於頻繁的調用的目的。

function debounce(func, wait) {
      let timeout;
      return function () {
        if (timeout) window.clearTimeout(timeout);
        timeout = window.setTimeout(function () {
          func.apply(this, arguments);
        }, wait);
      };
    }

調用apply改變傳入的func方法中的this指向,指向綁定事件的DOM元素。

節流

只要觸發,只會在當前計時器為空時,注冊計時器。

不斷觸發事件,只會在固定的事件間隔觸發。

setTimeout
function throttle(func, wait) {
      let timeout;
      return function () {
        if (!timeout) {
          timeout = window.setTimeout(function () {
            func.apply(this, arguments);
            timeout = null;
          }, wait);
        }
      };
    }
時間戳
 function throttleTime(func, wait) {
      let prev = 0;
      return function () {
        let now = Date.now();
        if (now - prev > wait) {
          func.apply(this);
          prev = now;
        }
      };
    }

所有

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=<device-width>, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <button id="bt1">防抖</button>
    <button id="bt2">節流</button>
  </body>
  <script>
    // 防抖
    function debounce(func, wait) {
      let timeout;
      return function () {
        if (timeout) window.clearTimeout(timeout);
        timeout = window.setTimeout(function () {
          func.apply(this, arguments);
        }, wait);
      };
    }
    // 節流
    function throttle(func, wait) {
      let timeout;
      return function () {
        if (!timeout) {
          timeout = window.setTimeout(function () {
            func.apply(this, arguments);
            timeout = null;
          }, wait);
        }
      };
    }
    function throttleTime(func, wait) {
      let prev = 0;
      return function () {
        let now = Date.now();
        if (now - prev > wait) {
          func.apply(this);
          prev = now;
        }
      };
    }
    let bt1 = document.getElementById("bt1");
    let bt2 = document.getElementById("bt2");
    bt1.onclick = debounce(function () {
      console.log(1);
    }, 1000);
    bt2.onclick = throttleTime(function () {
      console.log(2);
    }, 1000);
  </script>
</html>


免責聲明!

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



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