js函數節流(Throttle)

在瀏覽器 DOM 事件裏面,有一些事件會隨着用戶的操作不間斷觸發。比如:重新調整瀏覽器窗口大小(resize),瀏覽器頁面滾動(scroll),鼠標移動(mousemove)。

也就是說用戶在觸發這些瀏覽器操作的時候,如果腳本里面綁定了對應的事件處理方法,這個方法就不停的觸發。而當事件處理比較複雜的時候瀏覽器不斷執行計算,從而導致瀏覽器性能降低甚至卡死,影響用戶體驗。

下面我們就針對這一情況做函數的節流處理(以weindow.scroll爲例)。

1、簡單實現(未用閉包)

var timer = null;
window.onscroll = function () {
    clearTimeout(timer);
    timer = setTimeout(function() {
        console.log(new Date().getTime());
    }, 200);
};
2、利用閉包進行改進
var throttle = function (fn,delay) {
    var timer = null;
    return function () {
        clearTimeout(timer);
        timer = setTimeout(function() {
            fn();
        }, delay);
    }
};
function testFn (){
    console.log(new Date().getTime());
}
window.onscroll = throttle(testFn, 200);
3、利用函數的私有變量保存tId
function throttle (method,context,delay) {//context用來保存this指向
    clearTimeout(method.tId);
    method.tId = setTimeout(function () {
        method.call(context);
    },delay)
}
function testFn(){
    console.log(new Date().getTime());
}
window.onscroll = throttle(testFn,null,100);

上面這些方法已經可以起到節流效果了,但是會有一個問題。就是當用戶不斷的出發scroll事件的時候,我們所需要執行的函數一次也不會執行,所以我們就需要設置一個最小觸發時間,接下來我們對throttle函數再次進行改進。

//fn執行函數 delay停止觸發事件多長時間後執行函數 minTime不斷觸發時強制執行時間
var throttle = function (fn,delay,minTime) {
    var timer = null;
    var starTime = null;
    return function () {
        var now = +new Date();
        !starTime && (starTime = now);
        if( minTime && now - starTime > minTime ) {
            fn();
            starTime = now;//將開始時間重置
        }else{
            clearTimeout(timer);
            timer = setTimeout(function() {
                fn();
		starTime = null;
            }, delay);
        }
    }
};
function testFn(){
    console.log(new Date().getTime());
}
window.onscroll = throttle(testFn,200,300);

這樣只需要傳入minTime最小觸發時間就可以了。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章