1. 程式人生 > 其它 >JS函式節流和函式防抖

JS函式節流和函式防抖

前言:

在進行視窗的resize、scroll,輸入框內容校驗等操作時,如果事件處理函式呼叫的頻率無限制,會加重瀏覽器的負擔,導致使用者體驗非常糟糕。

此時我們可以採用debounce(防抖)和throttle(節流)的方式來減少呼叫頻率,同時又不影響實際效果。

函式防抖

函式防抖(debounce):當持續觸發事件時,一定時間段內沒有再觸發事件,事件處理函式才會執行一次,如果設定的時間到來之前,又一次觸發了事件,就重新開始延時。

如下圖,持續觸發scroll事件時,並不執行handle函式,當1000毫秒內沒有觸發scroll事件時,才會延時觸發scroll事件。

例項:

// 防抖
function debounce(func, wait=0) {    
   if (typeof func !== 'function') {
    throw new TypeError('need a function arguments')
   }
   let timeid = null;
        let result;
 
   return function() {
    let context = this;
    let args = arguments;

    if (timeid) {
      clearTimeout(timeid);
    }
    timeid = setTimeout(function() {
      result = func.apply(context, args);
    }, wait);
 
    return result;
   }
}
// 處理函式
function handle() {    
    console.log(Math.random()); 
}
// 滾動事件
window.addEventListener('scroll', debounce(handle, 1000));
            

當持續觸發scroll事件時,事件處理函式handle只在停止滾動1000毫秒之後才會呼叫一次,也就是說在持續觸發scroll事件的過程中,事件處理函式handle一直沒有執行。

函式節流

函式節流(throttle):當持續觸發事件時,保證一定時間段內只調用一次事件處理函式。

節流通俗解釋就比如我們水龍頭放水,閥門一開啟,水嘩嘩的往下流,秉著勤儉節約的優良傳統美德,我們要把水龍頭關小點,最好是如我們心意按照一定規律在某個時間間隔內一滴一滴的往下滴。

如下圖,持續觸發scroll事件時,並不立即執行handle函式,每隔1000毫秒才會執行一次handle函式。

例項:

節流throttle程式碼(時間戳):

let throttle = function(func, delay) {      
  let prev = Date.now();      
  return function() {        
    let context = this;        
    let args = arguments;        
    let now = Date.now();        
    if (now - prev >= delay) {          
      func.apply(context, args);          
      prev = Date.now();        
    }      
  }    
}    
function handle() {      
  console.log(Math.random());    
}    
window.addEventListener('scroll', throttle(handle, 1000));

節流throttle程式碼(定時器):

// 節流throttle程式碼(定時器):
let throttle = function(func, delay) {            
    let timer = null;            
    return function() {                
        let context = this;               
        let args = arguments;                
        if (!timer) {                    
            timer = setTimeout(function() {                        
                func.apply(context, args);                        
                timer = null;                    
            }, delay);                
        }            
    }        
}        
function handle() {            
    console.log(Math.random());        
}        
window.addEventListener('scroll', throttle(handle, 1000));

總結

函式防抖:將幾次操作合併為一此操作進行。原理是維護一個計時器,規定在delay時間後觸發函式,但是在delay時間內再次觸發的話,就會取消之前的計時器而重新設定。這樣一來,只有最後一次操作能被觸發。

函式節流:使得一定時間內只觸發一次函式。原理是通過判斷是否到達一定時間來觸發函式。

區別:函式節流不管事件觸發有多頻繁,都會保證在規定時間內一定會執行一次真正的事件處理函式,而函式防抖只是在最後一次事件後才觸發一次函式。

比如在頁面的無限載入場景下,我們需要使用者在滾動頁面時,每隔一段時間發一次 Ajax 請求,而不是在使用者停下滾動頁面操作時才去請求資料。這樣的場景,就適合用節流技術來實現。

PS:防抖和節流能有效減少瀏覽器引擎的損耗,防止出現頁面堵塞卡頓現象,應該熟練掌握。最後再次感謝原作者的總結,熱心分享技術讓我們的生活變得更好

參考連結:https://www.cnblogs.com/momo798/p/9177767.html