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

前言

事件的觸發(fā)權(quán)很多時(shí)候都屬于用戶(hù)骡显,有些情況下會(huì)產(chǎn)生問(wèn)題:
1.向后臺(tái)發(fā)送數(shù)據(jù),用戶(hù)頻繁觸發(fā)兢哭,對(duì)服務(wù)器造成壓力
2.一些瀏覽器事件:window.onresize诅挑、window.mousemove等,觸發(fā)的頻率非常高甲棍,會(huì)造成瀏覽器性能問(wèn)題
如果你碰到這些問(wèn)題简识,那就需要用到函數(shù)節(jié)流和防抖了。

一感猛、函數(shù)節(jié)流(throttle)

函數(shù)節(jié)流:一個(gè)函數(shù)執(zhí)行一次后七扰,只有大于設(shè)定的執(zhí)行周期后才會(huì)執(zhí)行第二次。
有個(gè)需要頻繁觸發(fā)函數(shù)陪白,出于優(yōu)化性能角度颈走,在規(guī)定時(shí)間內(nèi),只讓函數(shù)觸發(fā)的第一次生效咱士,后面不生效立由。

1.如何實(shí)現(xiàn)

其原理是用時(shí)間戳來(lái)判斷是否已到回調(diào)該執(zhí)行時(shí)間,記錄上次執(zhí)行的時(shí)間戳序厉,然后每次觸發(fā) scroll 事件執(zhí)行回調(diào)锐膜,回調(diào)中判斷當(dāng)前時(shí)間戳距離上次執(zhí)行時(shí)間戳的間隔是否已經(jīng)到達(dá) 規(guī)定時(shí)間段,如果是弛房,則執(zhí)行枣耀,并更新上次執(zhí)行的時(shí)間戳,如此循環(huán)庭再;

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<style>
    html,
    body {
        height: 500%; /*讓其出現(xiàn)滾動(dòng)條*/
    }
</style>
<body>
</body>
<script>
    function throttle(fn,delay) {
        // 記錄上一次函數(shù)觸發(fā)的時(shí)間
        var lastTime= 0;
        return function() {
            // 記錄當(dāng)前函數(shù)觸發(fā)的時(shí)間
            var nowTime=Date.now();
            if(nowTime-lastTime>delay) {
                // 修正this指向問(wèn)題
                fn.call(this);
                // 同步時(shí)間
                lastTime=nowTime;
            }
        }
    }
    document.onscroll =throttle(function(){
        console.log('scroll事件被觸發(fā)了'+ Date.now())
    },1000)
</script>
</html>
//上例中用到了閉包的特性--可以使變量lastTime的值長(zhǎng)期保存在內(nèi)存中捞奕。
2.函數(shù)節(jié)流的應(yīng)用場(chǎng)景

需要間隔一定時(shí)間觸發(fā)回調(diào)來(lái)控制函數(shù)調(diào)用頻率:
DOM 元素的拖拽功能實(shí)現(xiàn)(mousemove)
搜索聯(lián)想(keyup)
計(jì)算鼠標(biāo)移動(dòng)的距離(mousemove)
Canvas 模擬畫(huà)板功能(mousemove)
射擊游戲的 mousedown/keydown 事件(單位時(shí)間只能發(fā)射一顆子彈)
監(jiān)聽(tīng)滾動(dòng)事件判斷是否到頁(yè)面底部自動(dòng)加載更多:給 scroll 加了 debounce 后,只有用戶(hù)停止?jié)L動(dòng)后拄轻,才會(huì)判斷是否到了頁(yè)面底部颅围;如果是 throttle 的話,只要頁(yè)面滾動(dòng)就會(huì)間隔一段時(shí)間判斷一次


scorll.gif

二恨搓、函數(shù)防抖(debounce)

防抖函數(shù):一個(gè)需要頻繁觸發(fā)的函數(shù)院促,在規(guī)定時(shí)間內(nèi),只讓最后一次生效斧抱,前面的不生效常拓。

1.如何實(shí)現(xiàn)
其原理就第一次調(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í)器依啰,然后延遲一定時(shí)間再執(zhí)行。

    function debounce(fn,delay){
    // 記錄上一次的延時(shí)器
        var timer =null; 
        return function(){ // 清除上一次延時(shí)器
            clearTimeout(timer)
            timer =setTimeout(function(){fn.apply(this)},delay)  
            }
    }
    document.getElementById('btn').onclick =debounce(function(){
    console.log('點(diǎn)擊事件被觸發(fā)'+Date.now())
    },1000)
btn.gif

上例中也用到了閉包的特性--可以使變量timer的值長(zhǎng)期保存在內(nèi)存中店枣。

2.函數(shù)防抖的應(yīng)用場(chǎng)景

對(duì)于連續(xù)的事件響應(yīng)我們只需要執(zhí)行一次回調(diào):
1.每次 resize/scroll 觸發(fā)統(tǒng)計(jì)事件
2.文本輸入的驗(yàn)證(連續(xù)輸入文字后發(fā)送 AJAX 請(qǐng)求進(jìn)行驗(yàn)證速警,驗(yàn)證一次就好)

函數(shù)節(jié)流和函數(shù)去抖的核心其實(shí)就是限制某一個(gè)方法被頻繁觸發(fā),而一個(gè)方法之所以會(huì)被頻繁觸發(fā)鸯两,大多數(shù)情況下是因?yàn)?DOM 事件的監(jiān)聽(tīng)回調(diào)闷旧,而這也是函數(shù)節(jié)流以及防抖多數(shù)情況下的應(yīng)用場(chǎng)景。

總結(jié)

函數(shù)節(jié)流和函數(shù)去抖的核心其實(shí)就是限制某一個(gè)方法被頻繁觸發(fā)甩卓,而一個(gè)方法之所以會(huì)被頻繁觸發(fā)鸠匀,大多數(shù)情況下是因?yàn)?DOM 事件的監(jiān)聽(tīng)回調(diào)蕉斜,而這也是函數(shù)節(jié)流以及防抖多數(shù)情況下的應(yīng)用場(chǎng)景逾柿。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市宅此,隨后出現(xiàn)的幾起案子机错,更是在濱河造成了極大的恐慌,老刑警劉巖父腕,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件弱匪,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡璧亮,警方通過(guò)查閱死者的電腦和手機(jī)萧诫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)枝嘶,“玉大人帘饶,你說(shuō)我怎么就攤上這事∪悍觯” “怎么了及刻?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)竞阐。 經(jīng)常有香客問(wèn)我缴饭,道長(zhǎng),這世上最難降的妖魔是什么骆莹? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任颗搂,我火速辦了婚禮,結(jié)果婚禮上幕垦,老公的妹妹穿的比我還像新娘峭火。我一直安慰自己毁习,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布卖丸。 她就那樣靜靜地躺著纺且,像睡著了一般。 火紅的嫁衣襯著肌膚如雪稍浆。 梳的紋絲不亂的頭發(fā)上载碌,一...
    開(kāi)封第一講書(shū)人閱讀 51,443評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音衅枫,去河邊找鬼嫁艇。 笑死,一個(gè)胖子當(dāng)著我的面吹牛弦撩,可吹牛的內(nèi)容都是我干的步咪。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼益楼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼猾漫!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起感凤,我...
    開(kāi)封第一講書(shū)人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤悯周,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后陪竿,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體禽翼,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年族跛,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了闰挡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡礁哄,死狀恐怖长酗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情姐仅,我是刑警寧澤花枫,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站掏膏,受9級(jí)特大地震影響劳翰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜馒疹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一佳簸、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦生均、人聲如沸听想。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)汉买。三九已至,卻和暖如春佩脊,著一層夾襖步出監(jiān)牢的瞬間蛙粘,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工威彰, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留出牧,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓歇盼,卻偏偏與公主長(zhǎng)得像舔痕,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子豹缀,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 前言 瀏覽器中某些計(jì)算和處理要比其他的昂貴很多伯复。例如DOM操作比DOM交互需要更多的時(shí)間和cpu時(shí)間,為了提升性能...
    蛙哇閱讀 1,233評(píng)論 0 0
  • 前言 事件的觸發(fā)權(quán)很多時(shí)候都屬于用戶(hù)耿眉,有些情況下會(huì)產(chǎn)生問(wèn)題: 向后臺(tái)發(fā)送數(shù)據(jù)边翼,用戶(hù)頻繁觸發(fā)鱼响,對(duì)服務(wù)器造成壓力 一些...
    浪里行舟閱讀 1,337評(píng)論 0 10
  • 一.什么是函數(shù)防抖&節(jié)流 函數(shù)防抖函數(shù)防抖(debounce):在事件被觸發(fā)n秒后再執(zhí)行回調(diào)鸣剪,如果在這n秒內(nèi)又被觸...
    王蕾_fd49閱讀 431評(píng)論 0 1
  • 事件的觸發(fā)權(quán)很多時(shí)候都屬于用戶(hù),有些情況下會(huì)產(chǎn)生問(wèn)題: 向后臺(tái)發(fā)送數(shù)據(jù)丈积,用戶(hù)頻繁觸發(fā)筐骇,對(duì)服務(wù)器造成壓力 一些瀏覽器...
    oWSQo閱讀 429評(píng)論 0 6
  • 一、概念解釋?函數(shù)節(jié)流和函數(shù)防抖江滨,兩者都是優(yōu)化高頻率執(zhí)行js代碼的一種手段铛纬。?大家大概都知道舊款電視機(jī)的工作原理,...
    凌晨4點(diǎn)的簡(jiǎn)書(shū)閱讀 318評(píng)論 0 1