国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

你們都會的防抖與節流

beanlam / 1236人閱讀

摘要:關于防抖與節流的應用和解釋自行查找資料。修改如果有定時器就清除如果時間滿足就讓他不滿足總之除了第一次就只讓其中一個執行一開始執行一次時間戳,最后停止在執行一次。

這一篇文章我想寫一下防抖與節流,因為我自己不是很理解而且說實話,以前知道,但是老忘,雖然概念還有一些簡單的寫法會,但還是缺乏練習和深刻的理解。


當我們不加防抖或節流的時候就像這樣,鼠標滑過觸發這么多次,所以我們一個使用防抖或節流來限制它的請求次數而不是觸發次數。關于防抖與節流的應用和解釋自行查找資料。

function fn(e) { console.log(this); console.log(e); app.innerHTML = num ++; }

1.防抖

簡單實現

function debounce(fn, delay) {
    let timer = null;
    return function(){
        clearTimeout(timer);
        timer = setTimeout(function () {
            fn();
        }, delay);
    }
}

使用節流后

app.onmousemove = fdebounce(fn, 1000);


我們發現次數減少了太多,因為只要你在delay時間內不停地觸發就不會執行直到你的間隔時間大于delay才會執行。

我們來看一下this和event。

this是window,event是undefined。

修復this指向和事件參數

function debounce(fn, delay) {
    let timer = null,
        that;
    return function(e){
        that = this;
        clearTimeout(timer);
        timer = setTimeout(function () {  //this指向window(非嚴格模式)
            fn.apply(that, [e]);
        }, delay);
    }
}

或者是

function debounce(fn, delay) {
    let timer = null;
    return function(e){
        clearTimeout(timer);
        timer = setTimeout(()=>{ //箭頭函數
            fn.apply(this, [e]);
        }, delay);
    }
}

增強版(是否立即執行)

function debounce(fn, delay, immediate) {
    let timer = null,
        that; 
    return function (e) {
        that = this;
        clearTimeout(timer);
        if(immediate){  //是否立即執行
            if(!timer){  // 如果沒有設置定時器就先執行
                fn.apply(that, [e]);
            }
            timer = setTimeout(function () { 
                timer = null;// 設置定時器,使其在delay毫秒內不能執行,過了delay毫秒后在執行
            }, delay);
        }else{ //否則延時執行
            timer = setTimeout(function () {
                fn.apply(that, [e])
            }, delay);
        }
    };
}
//這個if...else只能執行一個,要不先執行,要不延時執行


一開始會執行一次,因為錄制不能顯示鼠標所以理解一下。

節流

簡易版(時間戳)

function throttle(fn, delay) {
    let last = 0, //上次執行時間
        now; //執行時的時間
    return function (e) {
        now = Date.now(); //當前時間
        if(now - last >= delay){  //如果兩次時間間隔大于delay,就執行
            last = now; //重新賦值
            fn(); 
        }
    };
}


在規定時間delay毫秒內總會執行一次事件。

setTimeout版本(修復this指向和事件參數)

function throttle(fn, delay) {
    let that,
        timer = null;
    return function (e) {
        that = this;
        if(!timer){  //如果沒設置定時器就執行
            timer = setTimeout(function () {
                fn.apply(that, [e]);
                timer = null; //果delay毫秒就設置timer,這樣就能delay執行一次
            }, delay);
        }
    };
}

修復this指向和事件參數(時間戳)

function throttle(fn, delay) {
    let last = 0, //上次執行時間
        now; //執行時的時間
    return function (e) {
        now = Date.now(); //當前時間
        if(now - last >= delay){  //如果兩次時間間隔大于delay,就執行
            last = now; //重新賦值
            fn.apply(this, [e]); 
        }
    };
}

區別

時間戳版本的會先執行

setTimeout版本的會后執行

所以可以結合一下他們兩個。

結合版

function throttle(fn, delay) {
    let last = 0,  //上次執行時間
        now, //當前時間
        leftTime, //剩余時間
        that, 
        timer = null;
    return function (e) {
        that = this;
        now = Date.now();
        leftTime = delay - (now - last); 
        if(leftTime <= 0){ //保證一開始就執行(先執行)
            last = now;
            fn.apply(that, [e]);
        }else{
            timer = setTimeout(function() {  //延時執行
                fn.apply(that, [e]);
                timer = null;
            },delay)
        }
    };
}

這樣做總體思路沒錯,但是第一次會執行以后就是兩個一起執行,因為條件都滿足。

修改

function throttle(fn, delay) {
    let last = 0,
        now,
        leftTime,
        that,
        timer = null;
    return function (e) {
        that = this;
        now = Date.now();
        leftTime = delay - (now - last);
        if(leftTime <= 0){
            if(timer){ //如果有定時器就清除
                clearTimeout(timer);
                timer = null;
            }
            last = now;
            fn.apply(that, [e]);
        }else if(!timer){
            timer = setTimeout(function() {
                last = now; //如果時間滿足就讓他不滿足
                //總之除了第一次就只讓其中一個執行
                fn.apply(that, [e]);
                timer = null;
            },delay)
        }
    };
}


一開始執行一次(時間戳),最后停止在執行一次(setTimeOut)。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/101084.html

相關文章

  • 小菊花課堂之JS的防抖與節流

    摘要:文章來源詳談防抖和節流輕松理解函數節流和函數防抖函數防抖和節流好啦,今天的小菊花課堂之的防抖與節流的內容就告一段落啦,感各位能耐心看到這里。 前言 陸游有一首《冬夜讀書示子聿》——古人學問無遺力,少壯工夫老始成。紙上得來終覺淺,絕知此事要躬行。,其中的意思想必大家都能明白,在學習或工作中,不斷的印證著這首詩的內涵。所以,又有了此篇小菊花文章。 詳解 在前端開發中,我們經常會碰到一些會持...

    leoperfect 評論0 收藏0
  • 小菊花課堂之JS的防抖與節流

    摘要:文章來源詳談防抖和節流輕松理解函數節流和函數防抖函數防抖和節流好啦,今天的小菊花課堂之的防抖與節流的內容就告一段落啦,感各位能耐心看到這里。 前言 陸游有一首《冬夜讀書示子聿》——古人學問無遺力,少壯工夫老始成。紙上得來終覺淺,絕知此事要躬行。,其中的意思想必大家都能明白,在學習或工作中,不斷的印證著這首詩的內涵。所以,又有了此篇小菊花文章。 詳解 在前端開發中,我們經常會碰到一些會持...

    Yangder 評論0 收藏0
  • 前端筆記(二) 對象的深淺拷貝,函數的防抖與節流,函數柯里化 ,圖片的預加載與懶加載

    摘要:對象是無法通過這種方式深拷貝。這就是函數防抖和節流要做的事情。函數防抖當觸發頻率過高時函數基本停止執行而函數節流則是按照一定的頻率執行事件。 對象的深淺拷貝 對象的深拷貝與淺拷貝的區別: 淺拷貝:僅僅復制對象的引用, 而不是對象本身。 深拷貝:把復制的對象所引用的全部對象都復制一遍 淺拷貝的實現: var obj = { age : 18, person : { ...

    dongxiawu 評論0 收藏0
  • 高級函數技巧-函數防抖與節流

    摘要:封裝方法也比較簡單,書中對此問題也進行了處理使用定時器,讓函數延遲秒后執行,在此秒內,然后函數再次被調用,則刪除上次的定時器,取消上次調用的隊列任務,重新設置定時器。 在實際開發中,函數一定是最實用最頻繁的一部分,無論是以函數為核心的函數式編程,還是更多人選擇的面向對象式的編程,都會有函數的身影,所以對函數進行深入的研究是非常有必要的。 函數節流 比較直白的說,函數節流就是強制規定一...

    whinc 評論0 收藏0
  • 函數防抖與函數節流

    摘要:函數節流保證如果電梯第一個人進來后,秒后準時運送一次,這個時間從第一個人上電梯開始計時,不等待,如果沒有人,則不運行。 前言 有一些瀏覽器事件我們不希望它很頻繁的觸發,如調整窗口大小(onresize)、監聽滾動條滾動(onscroll),如果這些監聽事件需要調用接口的話一秒內可能會調用上百次,這樣坑定是有問題的。 函數防抖(debounce) 如果有人進電梯(觸發事件),那電梯將在1...

    novo 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<