1. 程式人生 > 實用技巧 >JS - 函式防抖 & 函式節流

JS - 函式防抖 & 函式節流

函式節流

限制一個函式在一定時間內只能執行一次(無論觸發多少次,也都是每n秒後才執行一次)

主要用來防止頻繁觸發,優化程式效能,提高體驗等等

方法一:時間戳

這個方法通過判斷兩次獲取時間間隔長短來判斷是否執行函式

每次觸發時,只要到達指定時間點就會立即執行

觸發函式後立即執行,等待n秒後才執行第二次

    var $button1 = document.getElementById('button1');
    var num = 0;
    $button1.addEventListener('click', throttle(throttleCallback, 1000));
function
throttle(callBack, waitTime) { var time = Date.now(); return function() { var nowTime = Date.now(); var that = this; var args = arguments; /// 時間間隔判斷 if ( nowTime-time >= waitTime ) { callBack.apply(that, args);
// 觸發方法後更新點選時間 time = Date.now(); } else {} } } // 執行函式 function throttleCallback(e) { e.stopPropagation(); // 取消事件冒泡 num++; console.log(num); }

方法二:定時器

這個方法通過設定定時器延時執行函式

每次觸發時,需要到指定時間後才執行

觸發函式後不立即執行,等待n秒後才執行函式

    var $button2 = document.getElementById('button2');
    
var num = 0; $button2.addEventListener('click', DispatcherTimer(DispatcherTimerCallBack, 1000)); function DispatcherTimer(callBack, waitTime) { var timer = null; var wait = 200; // 儲存時間變數, 為了讓第一次點選時能立即執行 return function() { var that = this; var grgs = arguments; // 判斷是否存在定時器 if(!timer) { timer = setTimeout(function(){ callBack.apply(that, grgs); // 執行後清除定時器 clearTimeout(timer); timer = null; }, wait); } else {} wait = waitTime; // 儲存延遲時間 } } // 執行函式 function DispatcherTimerCallBack(e) { e.stopPropagation();//取消事件冒泡 num++; console.log(num); }

滑鼠事件節流

    window.addEventListener('mousemove', moveThrottle(moveThrottleCallBack, 1000));
    function moveThrottle(callBack, waitTime) {
        var timer = null;
        return function() {
            var grgs = arguments;
            // 判斷是否存在定時器
            if(!timer) { 
                timer = setTimeout(()=>{ 
                    callBack.apply(this, grgs);
                    // 執行完成後清除定時器,等待下一次執行
                    clearTimeout(timer);
                    timer = null;
                }, 1000); 
            }
        }
    }
    // 執行函式
    function moveThrottleCallBack(e){
        console.log('滑鼠事件節流');
    }

函式防抖

當持續觸發事件時,一定時間內沒有再觸發事件,事件函式才會執行一次。當在設定的時間之內又觸發了事件函式,就會重新開始計時

既是在一些高頻觸發事件裡,但其實只需要生效一次即可的函式,無論觸發多少次,值執行最後一次

    var $button3 = document.getElementById('button3');
    $button3.addEventListener('click', debounce(function(){
        console.log("點選事件 函式防抖")
    }, 500));
    function debounce(fn, waitTime) {
        var timer = null; 
        return function() {
            var that = this;
            // 每次觸發先清除定時器,再重新計算時間
            clearTimeout(timer);
            timer = null;
            timer = setTimeout(function(){
                fn.call(that);
            }, waitTime);
        }
    }

滑鼠事件

  var t = null; // 定時器
  window.addEventListener('mousemove', moveDebounce);
  function moveDebounce(e){
    // 每次觸發先清除定時器,再重新計算
    clearTimeout(t);
    t = null;
    t = setTimeout( ()=>{ move(e) }, 300 )
  }
  function move(e) {
    console.log('滑鼠事件防抖');
  }

滾動事件

    var t = null;// 定時器
    window.addEventListener('scroll', scrollDebounce);
    function scrollDebounce(e) {
        // 每次觸發先清除定時器,再重新計算
        clearTimeout(t);
        t = null;
        t = setTimeout( () => { scrollF(e) }, 300 );
    }
    function scrollF(e) {
        console.log("滾動事件");
    }