成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JS函數(shù)節(jié)流和函數(shù)防抖

doodlewind / 1297人閱讀

摘要:為什么需要函數(shù)防抖和函數(shù)節(jié)流在瀏覽器中某些計(jì)算和處理要比其他的昂貴很多。函數(shù)防抖如果一個(gè)事件被頻繁觸發(fā)多次,并且觸發(fā)的時(shí)間間隔過(guò)短,則防抖函數(shù)可以使得對(duì)應(yīng)的事件處理函數(shù)只執(zhí)行最后觸發(fā)的一次。函數(shù)防抖可以把多個(gè)順序的調(diào)用合并成一次。

1.為什么需要函數(shù)防抖和函數(shù)節(jié)流?

在瀏覽器中某些計(jì)算和處理要比其他的昂貴很多。例如DOM操作比起非DOM交互需要更多的內(nèi)存和CPU占用時(shí)間。連續(xù)嘗試進(jìn)行過(guò)多的DOM操作可能會(huì)導(dǎo)致瀏覽器掛起,甚至崩潰;

例如當(dāng)調(diào)整瀏覽器大小的時(shí)候,resize事件會(huì)連續(xù)觸發(fā);如果在resize事件處理程序內(nèi)部嘗試進(jìn)行DOM操作,其高頻率的更改可能會(huì)讓瀏覽器崩潰;

為了繞開上面的問(wèn)題,需要對(duì)該類函數(shù)進(jìn)行節(jié)流;

2.什么是函數(shù)防抖和函數(shù)節(jié)流
防抖(debounce)和節(jié)流(throttle)都是用來(lái)控制某個(gè)函數(shù)在一定時(shí)間內(nèi)執(zhí)行多少次的技巧,兩者相似而又不同。
背后的基本思想是某些代碼不可以在沒(méi)有間斷的情況下連續(xù)重復(fù)執(zhí)行。
2.1 函數(shù)防抖 (debounce)
如果一個(gè)事件被頻繁觸發(fā)多次,并且觸發(fā)的時(shí)間間隔過(guò)短,則防抖函數(shù)可以使得對(duì)應(yīng)的事件處理函數(shù)只執(zhí)行最后觸發(fā)的一次。
函數(shù)防抖可以把多個(gè)順序的調(diào)用合并成一次。
2.2 函數(shù)節(jié)流 (throttle)
如果一個(gè)事件被頻繁觸發(fā)多次,節(jié)流函數(shù)可以按照固定頻率去執(zhí)行對(duì)應(yīng)的事件處理方法。
函數(shù)節(jié)流保證一個(gè)事件一定時(shí)間內(nèi)只執(zhí)行一次。
3.應(yīng)用場(chǎng)景
類型 場(chǎng)景
函數(shù)防抖 1. 手機(jī)號(hào)、郵箱輸入檢測(cè)
2. 搜索框搜索輸入(只需最后一次輸入完后,再放松Ajax請(qǐng)求)
3. 窗口大小resize(只需窗口調(diào)整完成后,計(jì)算窗口大小,防止重復(fù)渲染)
4. 滾動(dòng)事件scroll(只需執(zhí)行觸發(fā)的最后一次滾動(dòng)事件的處理程序)
5. 文本輸入的驗(yàn)證(連續(xù)輸入文字后發(fā)送 AJAX 請(qǐng)求進(jìn)行驗(yàn)證,(停止輸入后)驗(yàn)證一次就好)
函數(shù)節(jié)流 1. DOM元素的拖拽功能實(shí)現(xiàn)(mousemove
2. 射擊游戲的 mousedown/keydown 事件(單位時(shí)間只能發(fā)射一顆子彈)
3. 計(jì)算鼠標(biāo)移動(dòng)的距離(mousemove
4. 搜索聯(lián)想(keyup
5. 滾動(dòng)事件scroll,(只要頁(yè)面滾動(dòng)就會(huì)間隔一段時(shí)間判斷一次)
4.如何實(shí)現(xiàn) 4.1 函數(shù)防抖實(shí)現(xiàn)
function debounce(fn, delay, scope) {
    let timer = null;
    // 返回函數(shù)對(duì)debounce作用域形成閉包
    return function () {
        // setTimeout()中用到函數(shù)環(huán)境總是window,故需要當(dāng)前環(huán)境的副本;
        let context = scope || this, args = arguments;
        // 如果事件被觸發(fā),清除timer并重新開始計(jì)時(shí)
        clearTimeout(timer);
        timer = setTimeout(function () {
            fn.apply(context, args);
        }, delay);
    }
}

代碼解讀

第一次調(diào)用函數(shù),創(chuàng)建一個(gè)定時(shí)器,在指定的時(shí)間間隔之后運(yùn)行代碼;

當(dāng)?shù)诙握{(diào)用該函數(shù)時(shí),它會(huì)清除前一次的定時(shí)器并設(shè)置另一個(gè);

如果前一個(gè)定時(shí)器已經(jīng)執(zhí)行過(guò)了,這個(gè)操作就沒(méi)有任何意義;

然而,如果前一個(gè)定時(shí)器尚未執(zhí)行,其實(shí)就是將其替換為一個(gè)新的定時(shí)器;

目的是只有在執(zhí)行函數(shù)的請(qǐng)求停止了delay時(shí)間之后才執(zhí)行。

4.2 函數(shù)節(jié)流實(shí)現(xiàn) 4.2.1 利用時(shí)間戳簡(jiǎn)單實(shí)現(xiàn)
function throttle(fn, threshold, scope) {
    let timer;
    let prev = Date.now();
    return function () {
        let context = scope || this, args = arguments;
        let now = Date.now();
        if (now - prev > threshold) {
            prev = now;
            fn.apply(context, args);
        }
    }
}
4.2.2 利用定時(shí)器簡(jiǎn)單實(shí)現(xiàn)
function throttle2(fn, threshold, scope) {
    let timer;
    return function () {
        let context = scope || this, args = arguments;
        if (!timer) {
            timer = setTimeout(function () {
                fn.apply(context, args);
                timer = null;
            }, threshold);
        }
    }
}
5 舉例(scroll事件) CSS代碼
    .wrap {
       width: 200px;
        height: 330px;
        margin: 50px;
        margin-top: 200px;
        position: relative;
        float: left;
        background-color: yellow;
    }
    .header{
        width: 100%;
        height: 30px;
        background-color: #a8d4f4;
        text-align: center;
        line-height: 30px;
    }
    .container {
        background-color: pink;
        box-sizing: content-box;
        width: 200px;
        height: 300px;
        overflow: scroll;
        position: relative;
    }
    .content {
        width: 140px;
        height: 800px;
        margin: auto;
        background-color: #14ffb2;
    }
HTML代碼
    
滾動(dòng)事件:普通
滾動(dòng)事件:加了函數(shù)防抖
滾動(dòng)事件:加了函數(shù)節(jié)流
JS代碼
    let els = document.getElementsByClassName("container");
    let count1 = 0,count2 = 0,count3 = 0;
    const THRESHOLD = 200;

    els[0].addEventListener("scroll", function handle() {
        console.log("普通滾動(dòng)事件!count1=", ++count1);
    });
    els[1].addEventListener("scroll", debounce(function handle() {
        console.log("執(zhí)行滾動(dòng)事件!(函數(shù)防抖) count2=", ++count2);
    }, THRESHOLD));
    els[2].addEventListener("scroll", throttle(function handle() {
        console.log(Date.now(),", 執(zhí)行滾動(dòng)事件!(函數(shù)節(jié)流) count3=", ++count3);
    }, THRESHOLD));
// 函數(shù)防抖
function debounce(fn, delay, scope) {
    let timer = null;
    let count = 1;
    return function () {
        let context = scope || this,
            args = arguments;
        clearTimeout(timer);
        console.log(Date.now(), ", 觸發(fā)第", count++, "次滾動(dòng)事件!");
        timer = setTimeout(function () {
            fn.apply(context, args);
            console.log(Date.now(), ", 可見(jiàn)只有當(dāng)高頻事件停止,最后一次事件觸發(fā)的超時(shí)調(diào)用才能在delay時(shí)間后執(zhí)行!");
        }, delay);
    }
}
// 函數(shù)節(jié)流
function throttle(fn, threshold, scope) {
    let timer;
    let prev = Date.now();
    return function () {
        let context = scope || this, args = arguments;
        let now = Date.now();
        if (now - prev > threshold) {
            prev = now;
            fn.apply(context, args);
        }
    }
}
效果截圖




6.總結(jié)

debouncethrottle均是通過(guò)減少高頻觸發(fā)事件的實(shí)際事件處理程序的執(zhí)行來(lái)提高事件處理函數(shù)運(yùn)行性能的手段,并沒(méi)有實(shí)質(zhì)上減少事件的觸發(fā)次數(shù)。

debounce可以把多個(gè)順序的調(diào)用合并成一次

throttle保證一個(gè)事件一定時(shí)間內(nèi)只執(zhí)行一次。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/99591.html

相關(guān)文章

  • 徹底弄懂函數(shù)防抖函數(shù)節(jié)流

    摘要:若時(shí)間差大于間隔時(shí)間,則立刻執(zhí)行一次函數(shù)。不同點(diǎn)函數(shù)防抖,在一段連續(xù)操作結(jié)束后,處理回調(diào),利用和實(shí)現(xiàn)。函數(shù)防抖關(guān)注一定時(shí)間連續(xù)觸發(fā)的事件只在最后執(zhí)行一次,而函數(shù)節(jié)流側(cè)重于一段時(shí)間內(nèi)只執(zhí)行一次。 原博客地址,歡迎star 函數(shù)防抖和節(jié)流 函數(shù)防抖和函數(shù)節(jié)流:優(yōu)化高頻率執(zhí)行js代碼的一種手段,js中的一些事件如瀏覽器的resize、scroll,鼠標(biāo)的mousemove、mouseover...

    Mr_houzi 評(píng)論0 收藏0
  • JS進(jìn)階篇3---函數(shù)節(jié)流” VS “防抖

    摘要:目的都是為了降低回調(diào)函數(shù)執(zhí)行頻率,節(jié)省計(jì)算機(jī)資源,優(yōu)化性能,提升用戶體驗(yàn)。函數(shù)防抖事件頻繁觸發(fā)的情況下,只有經(jīng)過(guò)足夠的空閑時(shí)間,才執(zhí)行代碼一次。 函數(shù)節(jié)流和函數(shù)防抖的對(duì)比分析 一、前言 前端開發(fā)中,函數(shù)節(jié)流(throttle) 和 函數(shù)防抖(debounce) 作為常用的性能優(yōu)化方法,兩者都是用于優(yōu)化高頻率執(zhí)行 js 代碼的手段,那具體它們有什么異同點(diǎn)呢?有對(duì)這兩個(gè)概念不太了解的小伙伴...

    hlcc 評(píng)論0 收藏0
  • 前端優(yōu)化 —— 函數(shù)節(jié)流防抖

    摘要:文件為函數(shù)要傳入的參數(shù)返回事件處理函數(shù)添加事件監(jiān)聽(tīng)節(jié)流函數(shù)一般用于事件的情況較多,因?yàn)檫@些事件的觸發(fā)是連續(xù)性的,需要在一個(gè)時(shí)間間隔內(nèi)只觸發(fā)一次。 showImg(https://segmentfault.com/img/remote/1460000018998747); 閱讀原文 前言 在前端開發(fā)當(dāng)中我們經(jīng)常會(huì)綁定一些事件觸發(fā)的某些程序執(zhí)行,有時(shí)這些事件會(huì)連續(xù)觸發(fā),如瀏覽器窗口 s...

    ralap 評(píng)論0 收藏0
  • 詳談js防抖節(jié)流

    摘要:本文會(huì)分別介紹什么是防抖和節(jié)流,它們的應(yīng)用場(chǎng)景,和實(shí)現(xiàn)方式。防抖和節(jié)流都是為了解決短時(shí)間內(nèi)大量觸發(fā)某函數(shù)而導(dǎo)致的性能問(wèn)題,比如觸發(fā)頻率過(guò)高導(dǎo)致的響應(yīng)速度跟不上觸發(fā)頻率,出現(xiàn)延遲,假死或卡頓的現(xiàn)象。 本文由小芭樂(lè)發(fā)表 0. 引入 首先舉一個(gè)例子: 模擬在輸入框輸入后做ajax查詢請(qǐng)求,沒(méi)有加入防抖和節(jié)流的效果,這里附上完整可執(zhí)行代碼: 沒(méi)有防抖 ...

    shevy 評(píng)論0 收藏0
  • js 防抖 節(jié)流 JavaScript

    摘要:此時(shí)需要采用防抖和節(jié)流的方式來(lái)減少調(diào)用頻率,同時(shí)不影響原來(lái)效果。函數(shù)防抖當(dāng)持續(xù)觸發(fā)事件時(shí),一段時(shí)間段內(nèi)沒(méi)有再觸發(fā)事件,事件處理函數(shù)才會(huì)執(zhí)行一次,如果設(shè)定的時(shí)間到來(lái)之前就觸發(fā)了事件,延時(shí)重新開始。 js 防抖 節(jié)流 JavaScript 實(shí)際工作中,通過(guò)監(jiān)聽(tīng)某些事件,如scroll事件檢測(cè)滾動(dòng)位置,根據(jù)滾動(dòng)位置顯示返回頂部按鈕;如resize事件,對(duì)某些自適應(yīng)頁(yè)面調(diào)整DOM的渲染;如ke...

    int64 評(píng)論0 收藏0
  • 小菊花課堂之JS防抖節(jié)流

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

    leoperfect 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<