摘要:函數節流指定時間間隔內只會執行一次任務函數防抖任務頻繁觸發的情況下,只有任務觸發的間隔超過指定間隔的時候,任務才會執行。使用函數節流與函數防抖的目的,在開頭的栗子中應該也能看得出來,就是為了節約計算機資源。
什么是函數節流與函數防抖
舉個栗子,我們知道目前的一種說法是當 1 秒內連續播放 24 張以上的圖片時,在人眼的視覺中就會形成一個連貫的動畫,所以在電影的播放(以前是,現在不知道)中基本是以每秒 24 張的速度播放的,為什么不 100 張或更多是因為 24 張就可以滿足人類視覺需求的時候,100 張就會顯得很浪費資源。再舉個栗子,假設電梯一次只能載一人的話,10 個人要上樓的話電梯就得走 10 次,是一種浪費資源的行為;而實際生活正顯然不是這樣的,當電梯里有人準備上樓的時候如果外面又有人按電梯的話,電梯會再次打開直到滿載位置,從電梯的角度來說,這時一種節約資源的行為(相對于一次只能載一個人)。
函數節流: 指定時間間隔內只會執行一次任務;
函數防抖: 任務頻繁觸發的情況下,只有任務觸發的間隔超過指定間隔的時候,任務才會執行。
函數節流(throttle)這里以判斷頁面是否滾動到底部為例,普通的做法就是監聽 window 對象的 scroll 事件,然后再函數體中寫入判斷是否滾動到底部的邏輯:
function onScroll() { // 判斷是否滾動到底部的邏輯 const pageHeight = $("body").height(); const scrollTop = $(window).scrollTop(); const winHeight = $(window).height(); const thresold = pageHeight - scrollTop - winHeight; if (thresold > -100 && thresold <= 20) { console.log("end"); } } $(window).on("scroll", onScroll);
這樣做的一個缺點就是比較消耗性能,因為當在滾動的時候,瀏覽器會無時不刻地在計算判斷是否滾動到底部的邏輯,而在實際的場景中是不需要這么做的,在實際場景中可能是這樣的:在滾動過程中,每隔一段時間在去計算這個判斷邏輯。而函數節流所做的工作就是每隔一段時間去執行一次原本需要無時不刻地在執行的函數,所以在滾動事件中引入函數的節流是一個非常好的實踐:
$(window).on("scroll", throttle(onScroll));
加上函數節流之后,當頁面再滾動的時候,每隔 300ms 才會去執行一次判斷邏輯。
簡單來說,函數的節流就是通過閉包保存一個標記(canRun = true),在函數的開頭判斷這個標記是否為 true,如果為 true 的話就繼續執行函數,否則則 return 掉,判斷完標記后立即把這個標記設為 false,然后把外部傳入的函數的執行包在一個 setTimeout 中,最后在 setTimeout 執行完畢后再把標記設置為 true(這里很關鍵),表示可以執行下一次的循環了。當 setTimeout 還未執行的時候,canRun 這個標記始終為 false,在開頭的判斷中被 return 掉。
function throttle(fn, interval = 300) { let canRun = true; return function () { if (!canRun) return; canRun = false; setTimeout(() => { fn.apply(this, arguments); canRun = true; }, interval); }; }函數防抖(debounce)
這里以用戶注冊時驗證用戶名是否被占用為例,如今很多網站為了提高用戶體驗,不會再輸入框失去焦點的時候再去判斷用戶名是否被占用,而是在輸入的時候就在判斷這個用戶名是否已被注冊:
$("input.user-name").on("input", function () { $.ajax({ url: `https://just.com/check`, method: "post", data: { username: $(this).val(), }, success(data) { if (data.isRegistered) { $(".tips").text("該用戶名已被注冊!"); } else { $(".tips").text("恭喜!該用戶名還未被注冊!"); } }, error(error) { console.log(error); }, }); });
很明顯,這樣的做法不好的是當用戶輸入第一個字符的時候,就開始請求判斷了,不僅對服務器的壓力增大了,對用戶體驗也未必比原來的好。而理想的做法應該是這樣的,當用戶輸入第一個字符后的一段時間內如果還有字符輸入的話,那就暫時不去請求判斷用戶名是否被占用。在這里引入函數防抖就能很好地解決這個問題:
$("input.user-name").on("input", debounce(function () { $.ajax({ url: `https://just.com/check`, method: "post", data: { username: $(this).val(), }, success(data) { if (data.isRegistered) { $(".tips").text("該用戶名已被注冊!"); } else { $(".tips").text("恭喜!該用戶名還未被注冊!"); } }, error(error) { console.log(error); }, }); }));
其實函數防抖的原理也非常地簡單,通過閉包保存一個標記來保存 setTimeout 返回的值,每當用戶輸入的時候把前一個 setTimeout clear 掉,然后又創建一個新的 setTimeout,這樣就能保證輸入字符后的 interval 間隔內如果還有字符輸入的話,就不會執行 fn 函數了。
function debounce(fn, interval = 300) { let timeout = null; return function () { clearTimeout(timeout); timeout = setTimeout(() => { fn.apply(this, arguments); }, interval); }; }總結
其實函數節流與函數防抖的原理非常簡單,巧妙地使用 setTimeout 來存放待執行的函數,這樣可以很方便的利用 clearTimeout 在合適的時機來清除待執行的函數。
使用函數節流與函數防抖的目的,在開頭的栗子中應該也能看得出來,就是為了節約計算機資源。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/100654.html
摘要:若時間差大于間隔時間,則立刻執行一次函數。不同點函數防抖,在一段連續操作結束后,處理回調,利用和實現。函數防抖關注一定時間連續觸發的事件只在最后執行一次,而函數節流側重于一段時間內只執行一次。 原博客地址,歡迎star 函數防抖和節流 函數防抖和函數節流:優化高頻率執行js代碼的一種手段,js中的一些事件如瀏覽器的resize、scroll,鼠標的mousemove、mouseover...
摘要:隆重請出主角防抖與節流。防抖與節流的異同相同都是防止某一時間段內,函數被頻繁調用執行,通過時間頻率控制,減少回調函數執行次數,來實現相關性能優化。參考文章分鐘理解的節流防抖及使用場景函數防抖和節流 showImg(https://segmentfault.com/img/bVburM8?w=800&h=600); 本篇課題,或許早已是爛大街的解讀文章。不過春招系列面試下來,不少伙伴們還...
摘要:基礎防抖我們現在寫一個最基礎的防抖處理標記事件也做如下改寫現在試一下,我們會發現只有我們停止滾動秒鐘的時候,控制臺才會打印出一行隨機數。 為何要防抖和節流 有時候會在項目開發中頻繁地觸發一些事件,如 resize、 scroll、 keyup、 keydown等,或者諸如輸入框的實時搜索功能,我們知道如果事件處理函數無限制調用,會大大加重瀏覽器的工作量,有可能導致頁面卡頓影響體驗;后臺...
摘要:文章來源詳談防抖和節流輕松理解函數節流和函數防抖函數防抖和節流好啦,今天的小菊花課堂之的防抖與節流的內容就告一段落啦,感各位能耐心看到這里。 前言 陸游有一首《冬夜讀書示子聿》——古人學問無遺力,少壯工夫老始成。紙上得來終覺淺,絕知此事要躬行。,其中的意思想必大家都能明白,在學習或工作中,不斷的印證著這首詩的內涵。所以,又有了此篇小菊花文章。 詳解 在前端開發中,我們經常會碰到一些會持...
摘要:文章來源詳談防抖和節流輕松理解函數節流和函數防抖函數防抖和節流好啦,今天的小菊花課堂之的防抖與節流的內容就告一段落啦,感各位能耐心看到這里。 前言 陸游有一首《冬夜讀書示子聿》——古人學問無遺力,少壯工夫老始成。紙上得來終覺淺,絕知此事要躬行。,其中的意思想必大家都能明白,在學習或工作中,不斷的印證著這首詩的內涵。所以,又有了此篇小菊花文章。 詳解 在前端開發中,我們經常會碰到一些會持...
摘要:函數防抖簡單實現模擬請求獲取函數的作用域和變量清除定時器節流名詞解釋連續執行函數,每隔一定時間執行函數。效果函數防抖是某一段時間內只執行一次函數節流是間隔時間執行,不管事件觸發有多頻繁,都會保證在規定時間內一定會執行一次真正的事件處理函數。 防抖(debounce) 名詞解釋:在事件被觸發n秒后再執行回調函數,如果在這n秒內又被觸發,則重新計時。 使用場景:以百度輸入框例,比如你要查詢...
閱讀 1944·2021-10-12 10:12
閱讀 3072·2019-08-30 15:44
閱讀 843·2019-08-30 15:43
閱讀 2994·2019-08-30 14:02
閱讀 2076·2019-08-30 12:54
閱讀 3497·2019-08-26 17:05
閱讀 1980·2019-08-26 13:34
閱讀 1051·2019-08-26 11:54