[TOC] #### 1. 節流介紹 --- 節流: n 秒內只運行一次,若在 n 秒內重復觸發,只有第一次生效 節流的應用場景: 1\. 滾動加載: 監聽頁面滾動到底部的時候觸發 2\. 拖拽場景: 固定時間只執行一次,防止高頻率的位置變動 #### 2. 滾動加載-節流處理 --- 首先編寫監聽頁面滾動距離的方法,當向下滑動時,可以看到控制臺執行了很多次的輸出,如果我們要根據頁面滑動距離來計算代碼邏輯,這樣頻繁的執行計算會非常損耗系統性能,我們可以使用節流來優化這個問題 ``` <style> body { height: 2000px; background: lightsalmon; } </style> <script> let count = 1 function scrollFn() { console.log('監聽頁面滾動次數: ', count++); } document.onscroll = scrollFn </script> ``` 節流的實現思路: 1\. 借助 setTimeout 定時器,控制事件回調是否執行 2\. 獲取每次事件執行的時間與上一次執行的時間差 3\. 判斷時間差是否已超過設定的時間間隔,超過時立即執行函數,沒有超過時取消后續的定時器任務 4\. 最后一次事件的觸發,會執行完成 使用節流函數優化后的代碼: ```javascript // 節流函數 function throttle(fn, time) { // 上一次的執行時間 let pre = 0 let timeout = null return function (...args) { const now = Date.now() // 時間差超過了設定的時間間隔 if (now - pre > time) { pre = now fn.apply(this, args) } else { // 沒有超過設定的時間間隔,則后續的事件會直接清除 if (timeout) { clearTimeout(timeout) timeout = null } // 最后一次的事件會觸發 timeout = setTimeout(() => { pre = now fn.apply(this, args) }, time); } } } document.onscroll = throttle(scrollFn, 300) ```