題解 UVA12727 The Sightseeing Tour
阿新 • • 發佈:2021-08-24
防抖與節流
- 目的:防抖和節流嚴格算起來應該屬於效能優化的知識,但實際上遇到的頻率相當高,處理不當或者放任不管就容易引起瀏覽器卡死。
防抖
-
定義:對於短時間內連續觸發的事件(上面的滾動事件),防抖的含義就是讓某個時間期限(如上面的1000毫秒)內,事件處理函式只執行一次。
-
/*****************************簡化後的分割******************************/ function debounce(fn,delay){ let timer = null //藉助閉包 return function() { if(timer){ clearTimeout(timer) } timer = setTimeout(fn,delay) // 簡化寫法 } } // 然後是舊程式碼 function showTop () { var scrollTop = document.body.scrollTop || document.documentElement.scrollTop; console.log('滾動條位置:' + scrollTop); } window.onscroll = debounce(showTop,1000) // 為了方便觀察效果我們取個大點的間斷值,實際使用根據需要來配置
節流
-
function throttle(fn,delay){ let valid = true return function() { if(!valid){ //休息時間 暫不接客 return false } // 工作時間,執行函式並且在間隔期內把狀態位設為無效 valid = false setTimeout(() => { fn() valid = true; }, delay) } } /* 請注意,節流函式並不止上面這種實現方案, 例如可以完全不借助setTimeout,可以把狀態位換成時間戳,然後利用時間戳差值是否大於指定間隔時間來做判定。 也可以直接將setTimeout的返回的標記當做判斷條件-判斷當前定時器是否存在,如果存在表示還在冷卻,並且在執行fn之後消除定時器表示啟用,原理都一樣 */ // 以下照舊 function showTop () { var scrollTop = document.body.scrollTop || document.documentElement.scrollTop; console.log('滾動條位置:' + scrollTop); } window.onscroll = throttle(showTop,1000)
-
執行以上程式碼的結果是:
如果一直拖著滾動條進行滾動,那麼會以1s的時間間隔,持續輸出當前位置和頂部的距離
使用場景
- 搜尋框input事件,例如要支援輸入實時搜尋可以使用節流方案(間隔一段時間就必須查詢相關內容),或者實現輸入間隔大於某個值(如500ms),就當做使用者輸入完成,然後開始搜尋,具體使用哪種方案要看業務需求。
- 頁面resize事件,常見於需要做頁面適配的時候。需要根據最終呈現的頁面情況進行dom渲染(這種情形一般是使用防抖,因為只需要判斷最後一次的變化情況)