1. 程式人生 > 其它 >題解 UVA12727 The Sightseeing Tour

題解 UVA12727 The Sightseeing Tour

防抖與節流

  • 目的:防抖和節流嚴格算起來應該屬於效能優化的知識,但實際上遇到的頻率相當高,處理不當或者放任不管就容易引起瀏覽器卡死。

防抖

  • 定義:對於短時間內連續觸發的事件(上面的滾動事件),防抖的含義就是讓某個時間期限(如上面的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渲染(這種情形一般是使用防抖,因為只需要判斷最後一次的變化情況)

用第三方庫 lodash