1. 程式人生 > >函式防抖與節流

函式防抖與節流

一、概念解釋

 函式節流和函式防抖,兩者都是優化高頻率執行js程式碼的一種手段。
 大家大概都知道舊款電視機的工作原理,就是一行行得掃描出色彩到螢幕上,然後組成一張張圖片。由於肉眼只能分辨出一定頻率的變化,當高頻率的掃描,人類是感覺不出來的。反而形成一種視覺效果,就是一張圖。就像高速旋轉的風扇,你看不到扇葉,只看到了一個圓一樣。
 同理,可以類推到js程式碼。在一定時間內,程式碼執行的次數不一定要非常多。達到一定頻率就足夠了。因為跑得越多,帶來的效果也是一樣。倒不如,把js程式碼的執行次數控制在合理的範圍。既能節省瀏覽器CPU資源,又能讓頁面瀏覽更加順暢,不會因為js的執行而發生卡頓。這就是函式節流和函式防抖要做的事。

 函式節流是指一定時間內js方法只跑一次。比如人的眨眼睛,就是一定時間內眨一次。這是函式節流最形象的解釋。
 函式防抖是指頻繁觸發的情況下,只有足夠的空閒時間,才執行程式碼一次。比如生活中的坐公交,就是一定時間內,如果有人陸續刷卡上車,司機就不會開車。只有別人沒刷卡了,司機才開車。

二、函式節流

 函式節流應用的實際場景,多數在監聽頁面元素滾動事件的時候會用到。因為滾動事件,是一個高頻觸發的事件。以下是監聽頁面元素滾動的示例程式碼:

// 函式節流
var canRun = true;
document.getElementById("throttle").onscroll = function
(){
if(!canRun){ // 判斷是否已空閒,如果在執行中,則直接return return; } canRun = false; setTimeout(function(){ console.log("函式節流"); canRun = true; }, 300); };

 函式節流的要點是,宣告一個變數當標誌位,記錄當前程式碼是否在執行。
 如果空閒,則可以正常觸發方法執行。
 如果程式碼正在執行,則取消這次方法執行,直接return。

 這個方法的作用是監聽ID為throttle元素的滾動事件。
 當canRun為true,則代表現在的滾動處理事件是空閒的,可以使用。
 通過關卡if(!canRun),等於就拿到了通行證。然後下一步的操作就是立馬將關卡關上canRun=false。這樣,其他請求執行滾動事件的方法,就被擋回去了。
 接著用setTimeout規定最小的時間間隔300,接著再執行setTimeout方法體裡面的內容。
 最後,等setTimeout裡面的方法都執行完畢,才釋放關卡canRun=true,允許下一個訪問者進來。
 這個函式節流的實現形式,需要注意的是執行的間隔時間是>=300ms。如果具體執行的方法是包含callback的,也可以將canRun=true這一步放到callback中。理解了函式節流的關卡設定重點,其實改起來就簡單多了。

三、函式防抖

 函式防抖的應用場景,最常見的就是使用者註冊時候的手機號碼驗證和郵箱驗證了。只有等使用者輸入完畢後,前端才需要檢查格式是否正確,如果不正確,再彈出提示語。以下還是以頁面元素滾動監聽的例子,來進行解析:

// 函式防抖
var timer = false;
document.getElementById("debounce").onscroll = function(){
    clearTimeout(timer); // 清除未執行的程式碼,重置回初始化狀態

    timer = setTimeout(function(){
        console.log("函式防抖");
    }, 300);
};

 函式防抖的要點,也是需要一個setTimeout來輔助實現。延遲執行需要跑的程式碼。
 如果方法多次觸發,則把上次記錄的延遲執行程式碼用clearTimeout清掉,重新開始。
 如果計時完畢,沒有方法進來訪問觸發,則執行程式碼。

 這個方法的作用是監聽ID為debounce元素的滾動事件
 進入滾動事件方法體的時候,做的第一件事就是清除上次未執行的setTimeout。而setTimeout的引用id由變數timer記錄。
 clearTimeout方法,允許傳入無效的值。所以這裡直接執行clearTimeout即可。
 然後,將需要執行的程式碼放入setTimeout中,再返回setTimeout引用給timer快取。
 如果倒計時300ms以後,還沒有新的方法觸發滾動事件,則執行setTimeout中的程式碼。
 函式防抖的實現重點,就是巧用setTimeout做快取池,而且可以輕易地清除待執行的程式碼。
 其實,用佇列的方式也可以做到這種效果。這裡就不深入了。

四、線上demo

函式節流和函式防抖
 這是我寫的一個測試demo,把滑鼠移動到模組上方,滾動滾輪,即可在控制檯檢視輸出效果。

相關推薦

Javascript函式節流

為什麼要函式防抖和函式節流? 知乎上的回答有很經典的例子: 舉個栗子,我們知道目前的一種說法是當 1 秒內連續播放 24 張以上的圖片時,在人眼的視覺中就會形成一個連貫的動畫,所以在電影的播放(以前是,現在不知道)中基本是以每秒 24 張的速度播放的,為什麼不 100 張或更

函式節流

一、概念解釋  函式節流和函式防抖,兩者都是優化高頻率執行js程式碼的一種手段。  大家大概都知道舊款電視機的工作原理,就是一行行得掃描出色彩到螢幕上,然後組成一張張圖片。由於肉眼只能分辨出一定頻率的變化,當高頻率的掃描,人類是感覺不出來的。反而形成一種視覺

前端開發的函式函式節流

最近在開發中遇到一個問題,如果在很短的事件內連續點選同一個按鈕,按鈕的事件會觸發多次,在網上查了一下資料發現undescore.js 這個工具外掛,裡面提供了這樣兩個函式 debounce 和  thr

[譯]例項詳解節流(乾貨!!!)

lodash原始碼中推薦的文章,為了學習(英語),翻譯了一下~ 原文連結 作者:DAVID CORBACHO 本文來自一位倫敦前端工程師DAVID CORBACHO的技術投稿。我們在之前討論過這個話題(關於防抖與節流),但這次,DAVID CORBACHO通過生動的演示會將它們講的十分清晰,通俗易懂。

優化 ~ 節流

一:函式的節流: 一定時間內只觸發一次  可以是直接給一個定時器,按時觸發, // 函式節流 var canRun = true; document.getElementById("throttle"). onscroll = function(){ if(!canRun){ // 判斷是

工具函式--節流

防抖和節流 視窗的resize、scroll,輸入框內容校驗等操作時,如果這些操作處理函式較為複雜或頁面頻繁重渲染等操作時,如果事件觸發的頻率無限制,會加重瀏覽器的負擔,導致使用者體驗非常糟糕。此時我們可以採用debounce(防抖)和throttle(節流)

JS的節流

在進行視窗的resize、scroll,輸入框內容校驗等操作時,如果事件處理函式呼叫的頻率無限制,會加重瀏覽器的負擔,導致使用者體驗非常糟糕。此時我們可以採用debounce(防抖)和throttle(節流)的方式來減少呼叫頻率,同時又不影響實際效果。   函式防抖 &nb

函式節流

在前端開發的過程中,我們經常會需要繫結一些持續觸發的事件,如 resize、scroll、mousemove 等等,但有些時候我們並不希望在事件持續觸發的過程中那麼頻繁地去執行函式。 通常這種情況下我們怎麼去解決的呢?一般來講,防抖和節流是比較好的解決方案。 讓我們先來看

函數的節流

-s 執行函數 title 滾動 onscroll inf 我們 dom 文章 函數節流與函數防抖(以及它們的使用場景) 時間:2019-02-27 本文章向大家介紹函數節流與函數防抖(以及它們的使用場景),主要包括函數節流與函數防抖(以及它們的使用場景)使

JS節流函數封裝

函數 滾動 sta ner ott const eve else deb 防抖 在監聽scroll事件的時候經常會用到防抖,當滾動到某一位置而觸發狀態,從而不會出現頻繁滾動持續觸發事件的情況 防抖的事件處理機制僅觸發一次且必須是結束狀態下才會執行 function de

函數節流

like 後臺 uri div 而在 內容 瀏覽器 提交按鈕 https 函數防抖與節流 underscore.js提供了很多很有用的函數,今天想說說其中的兩個。這兩個函數都用於限制函數的執行 debounce 在解釋這個函數前,我們先從一個例子看下這個函數的使

JS中的節流

-s ons 指定 多少 out 你在 圖片 return var 什麽是防抖?and什麽是節流?一起來開心的學習下吧。 首先什麽是防抖:就是在一定的時間內事件只發生一次,比如你點擊button按鈕,1秒內任你單身30年手速點擊無數次,他也還是只觸發一次。舉個例子,當你在

節流函數

需要 spa 選擇 timeout 定時 場景 lse div col 場景:在開發搜索框的過程中,為了防止高頻觸發,減少不必要的性能浪費。我們需要用一種機制來阻止高頻觸發 兩種實現方案: 1.防抖函數:在一定時間內多次執行以最後一次執行為準 const

節流 & 若每個請求必須傳送,如何平滑地獲取最後一個介面返回的資料

部落格地址:https://ainyi.com/79 日常瀏覽網頁中,在進行視窗的 resize、scroll 或者重複點選某按鈕傳送請求,此時事件處理函式或者介面呼叫的頻率若無限制,則會加重瀏覽器的負擔,介面可能顯示有誤,服務端也可能出問題,導致使用者體驗非常糟糕 此時可以採用 debounce(防抖)和

“淺入淺出”函式(debounce)節流(throttle)

函式防抖與節流是日常開發中經常用到的技巧,也是前端面試中的常客,但是發現自己工作一年多了,要麼直接複用已有的程式碼或工具,要麼抄襲《JS高階程式設計》書中所述“函式節流”,(實際上紅寶書上的實現類似是函式防抖而不是函式節流),還沒有認真的總結和親自實現這兩個方法,實在是一件蠻丟臉的事。網上關於這方面的資料簡直

進階之函式節流函式

原文標題:函式節流與函式防抖 原文地址:https://justclear.github.io/throttle-and-debounce/ 原文作者:justclear   什麼是函式節流與函式防抖 舉個栗子,我們知道目前的一種說法是當 1 秒內連續播放 24 張以上

函式節流函式

在上一篇部落格js事件全解中提到了事件的各種用法,有時我們希望一些事件如scroll,resize,keyup等多次觸發,但如果過於頻繁,會導致介面卡頓,甚至瀏覽器崩潰。為了不影響效能,又需要限制

函式節流函式的區別

函式節流與函式防抖是我們解決頻繁觸發DOM事件的兩種常用解決方案,但是經常傻傻分不清楚。。。這不,在專案中又用遇到了,在此處記錄一下 函式防抖 debounce 原理:將若干函式呼叫合成為一次,並在給定時間過去之後,或者連續事件完全觸發完成之後,呼叫一次

面試之函式節流函式

從場景說起 滑動到底部繼續載入,是移動端很常見的一種場景。 通常來說,我們會在對可滑動區域(一般是window)的scroll事件做監聽,判斷距離底部還有多遠,如果距離底部較近,則發起HTTP請求,請求下一頁的資料。 很容易寫出這樣的程式碼: let page

一個函式實現函式節流函式

函式節流和函式防抖 今天在研究函式防抖和節流的過程中,發現這個方法已經把節流和防抖合二為一了,我很困惑,難道是我對節流和防抖的概念搞錯了。 函式節流:使連續執行的事件或函式,變為固定時間間隔執行。 函式防抖:使連續執行的事件或函式,在停止執行後只觸發一次。