觸發高頻事件後n秒內函數只會執行一次,若是n秒內高頻事件再次被觸發,則從新計算時間
var time = null; document.onmousewheel = function(e){ if (time) { clearTimeout(time) } time = setTimeout( () => { /* 進行滾動操做 */ time = null }, 100) } # 第一次滑動時 time 是null ,直接執行 setTimeout ,在 0.1s 內若是又繼續滑動了滾輪, # 就會清除上一次的 setTimeout ,直到在 0.1s 內沒有滑動滾輪,就會執行 setTimeout 中 # 的內容。
高頻事件觸發,但在n秒內只會執行一次,因此節流會稀釋函數的執行頻率
下面是js代碼,這種方式有點很差理解閉包
function throttle() { let canRun = true; // 經過閉包保存一個標記 return function () { console.log(canRun) if (!canRun) return; // 在函數開頭判斷標記是否爲true,不爲true則return canRun = false; // 當即設置爲false setTimeout(() => { // 將外部傳入的函數的執行放在setTimeout中 // 最後在setTimeout執行完畢後再把標記設置爲true(關鍵)表示能夠執行下一次循環了。 // 當定時器沒有執行的時候標記永遠是false,在開頭被return掉 console.log(1) canRun = true; }, 1000); }; } window.addEventListener('resize', throttle()); # 當函數被註冊的時候,定義了 canRun 爲 true,以後返回一個函數, # 每當事件被觸發的時候,執行返回的函數中的內容。首先判斷 canRun, # 若是爲 true 就往下執行,而後設 canRun 爲 false,執行定時器, # 在接下來的 1s 內,若是再次觸發 resize 事件,canRun 的值是 false , # 會直接 return 空,不會執行任何操做。當 1s 後執行了定時器中的 # 內容並設置 canRun 爲 true 後,觸發事件纔會從新執行定時器。 ***注意*** 1. 在添加事件的時候,後面的函數是加()的。正由於這個括號,因此在註冊 事件的時候,let canRun = true 會被執行一次,而在事件被觸發的時候, let canRun = true 是不會被執行的,只有在被註冊時會被執行一次。 2. 觸發事件之後,執行的是 throttle 函數返回的函數,而不是 throttle 函數。
這兩種方式的區別:第一種是當 0.1s 內再次觸發事件,會消除定時器,從新計算,適用於滾輪滾動後頁面的切換。由於用戶滾輪切換頁面時,一次會滾動不少下;第二種是若是事件一直在觸發,可是每 1s 會執行一次。函數