js-函數節流和防抖

一.什么是函數防抖&節流

  • 函數防抖

    函數防抖(debounce):在事件被觸發n秒后再執行回調,如果在這n秒內又被觸發,則重新計時

  • 函數節流(throttle):

    當持續觸發事件時,在規定時間段內只能調用一次回調函數。

    如果在規定時間內觸發了該事件,則什么也不做,也不會重新計時,即使一直觸發,也是每隔n秒執行一次回調

  • 相同點/不同點

    相同:都是限制回調函數調用頻率,避免大量計算導致的頁面卡頓.

    不同:防抖是將多次執行變為最后一次執行,節流是將多次執行變為每隔一段時間執行一次回調函數.

二.為什么需要函數防抖&節流

前端開發過程中,有一些事件,常見的例如,onresizescrollmousemove ,mousehover 等,會被頻繁觸發(短時間內多次觸發),不做限制的話,有可能一秒之內執行幾十次、幾百次,如果在這些函數內部執行了其他函數,尤其是執行了操作 DOM 的函數(瀏覽器操作 DOM 是很耗費性能的),那不僅會浪費計算機資源,還會降低程序運行速度,甚至造成瀏覽器卡死、崩潰。這種問題顯然是致命的。

在例如回調函數里面代碼塊比較沉重時,這樣頻繁觸發,就會大大降低性能了

除此之外,短時間內重復的 ajax 調用不僅會造成數據關系的混亂,還會造成網絡擁塞,增加服務器壓力,顯然這個問題也是需要解決的

三.函數的防抖

  • 防抖的思路

    函數防抖的要點,是需要一個 setTimeout 來輔助實現,延遲運行需要執行的代碼。如果方法多次觸發,則把上次記錄的延遲執行代碼用 clearTimeout 清掉,重新開始計時。若計時期間事件沒有被重新觸發,等延遲時間計時完畢,則執行目標代碼

    既然前面都提到了計時,那實現的關鍵就在于setTimeOut這個函數,由于還需要一個變量來保存計時,考慮維護全局純凈,可以借助閉包來實現:

  • 防抖代碼實現

    function debounce(fn, delay) {
       // 創建一個標記用來存放定時器的返回值
       var timer = null;
       return function (e) {
           // 每當用戶輸入的時候把前一個 setTimeout clear 掉
           clearTimeout(timer);
           // 然后又創建一個新的 setTimeout,
           // 樣就能保證interval 間隔內如果時間持續觸發,
           // 就不會執行 fn 函數
           timer = setTimeout(() => {
             //這個this的修正是為了handle函數里面的this指向事件偵聽對象,就是docment元素,
             //如果不修正handle函數中的this就指向window
             //還有這個arguments 是為了參數 e 穿到handle函數中
             fn.apply(this, arguments); 
           }, delay);
       };
    }
    
    // 處理函數
    function handle(e) {
      this.style.color="red";
     console.log(this);
     console.log('防抖:', Math.random());
    }
    
    var bn=document.querySelector("button");
    bn.addEventListener("click",debounce(handle, 500));
    
  • 應用場景

    函數防抖一般用在什么情況之下呢?一般用在,連續的事件只需觸發一次回調的場合。具體有:

    兩個條件:

    • 如果客戶連續的操作會導致頻繁的事件回調(可能引起頁面卡頓).
    • 客戶只關心"最后一次"操作(也可以理解為停止連續操作后)所返回的結果.

    例如:

    1. 搜索框搜索輸入。只需用戶最后一次輸入完,再發送請求;
    2. 用戶名、手機號、郵箱輸入驗證;
    3. 給按鈕加函數防抖 防止表單多次提交
    4. 按鈕點擊:收藏,點贊,心標等

四.函數的節流

  • 節流的思路

    第一次先設定一個變量true,第二次執行這個函數時,會判斷變量是否true,是則返回。

    當第一次的定時器執行完函數最后會設定變量為flase。

    那么下次判斷變量時則為flase,函數會依次運行

  • 節流代碼的實現

    function throttle(fn, delay = 100) {
               //首先設定一個變量,在沒有執行我們的定時器時為null
               let timer = null;
               return function () {
                   //當我們發現這個定時器存在時,則表示定時器已經在運行中,需要返回
                   if (timer) return;
                   timer = setTimeout(() => {
                       fn.apply(this, arguments);
                       timer = null;
                   }, delay);
               }
           }
    
    // 處理函數
    function handle(e) {
     console.log(this);
     console.log('節流:', Math.random());
    }
    
    var bn = document.querySelector("button");
    bn.addEventListener("click", throttle(handle, 500));
    
  • 應用場景

    兩個條件:

    • 客戶連續頻繁地觸發事件
    • 客戶不再只關心"最后一次"操作后的結果反饋.而是在操作過程中持續的反.

    例如:

    1.onscroll滾動時候的

    2.游戲中的刷新率
    3.DOM元素拖拽

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,488評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,034評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,327評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,554評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,337評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,883評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,975評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,114評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,625評論 1 332
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,555評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,737評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,244評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,973評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,615評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,343評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,699評論 2 370