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