這篇文章帶給大家的內容是關於JavaScript防手震和節流的應用以及實作方法介紹(程式碼範例),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。
先舉一個例子:
模擬在輸入框輸入後做ajax查詢請求,沒有加入防手震和節流的效果,這裡附上完整可執行程式碼:
nbsp;html> <meta> <title>没有防抖</title> <style></style> <script> window.onload = function () { //模拟ajax请求 function ajax(content) { console.log('ajax request ' + content) } let inputNormal = document.getElementById('normal'); inputNormal.addEventListener('keyup', function (e) { ajax(e.target.value) }) } </script> <div> 1.没有防抖的输入: <input> </div>
效果:在輸入框裡輸入一個,就會觸發一次「ajax請求」(這裡是console)。
沒有防手震和節流
缺點:浪費請求資源,可以加入防手震和節流來最佳化。
本文會分別介紹什麼是防手震和節流,它們的應用場景,和實作方式。防手震和節流都是為了解決短時間內大量觸發某函數而導致的效能問題,例如觸發頻率過高導致的反應速度跟不上觸發頻率,出現延遲,假死或卡頓的現象。但二者應對的業務需求不一樣,所以實現的原則也不一樣,下面具體來看看吧。
1. 防手震(debounce)
1.1 什麼是防手震
在事件觸發n秒後再執行回呼函數,如果在這n秒內又被觸發,則重新計時。
1.2 應用程式場景
(1) 使用者在輸入框中連續輸入一串字元後,只會在輸入完後去執行最後一次的查詢ajax請求,這樣可以有效減少請求次數,節省請求資源;
(2) window的resize、scroll事件,不斷地調整瀏覽器的視窗大小、或捲動時會觸發對應事件,防抖讓其只觸發一次;
1.3 實作
還是上述列子,這裡加入防手震來最佳化一下,完整程式碼如下:
nbsp;html> <meta> <title>加入防抖</title> <style></style> <script> window.onload = function () { //模拟ajax请求 function ajax(content) { console.log('ajax request ' + content) } function debounce(fun, delay) { return function (args) { //获取函数的作用域和变量 let that = this let _args = args //每次事件被触发,都会清除当前的timeer,然后重写设置超时调用 clearTimeout(fun.id) fun.id = setTimeout(function () { fun.call(that, _args) }, delay) } } let inputDebounce = document.getElementById('debounce') let debounceAjax = debounce(ajax, 500) inputDebounce.addEventListener('keyup', function (e) { debounceAjax(e.target.value) }) } </script> <div> 2.加入防抖后的输入: <input> </div>
程式碼說明:
1.每一次事件被觸發,都會清除當前的timer 然後重新設定超時調用,即重新計時。這就會導致每一次高頻事件都會取消前一次的超時調用,導致事件處理程序不能被觸發;
2.只有當高頻事件停止,最後一次事件觸發的超時調用才能在delay時間後執行;
效果:
加入防手震後,當持續在輸入框內輸入時,並不會發送請求,只有在指定時間間隔內沒有再輸入時,才會發送請求。如果先停止輸入,但是在指定間隔內再輸入,會重新觸發計時。
加入防手震
2.節流(throttle)
2.1 什麼是節流
規定一個單位時間,在這個單位時間內,只能有一次觸發事件的回呼函數執行,如果在同一個單位時間內某事件被觸發多次,只有一次能生效。
2.2 應用場景
(1)滑鼠連續不斷地觸發某事件(如點擊),只在單位時間內只觸發一次;
#(2)在頁面的無限載入場景下,需要使用者在滾動頁面時,每隔一段時間發一次ajax 請求,而不是在使用者停下滾動頁面操作時才去請求資料;
(3)監聽滾動事件,例如是否滑到底部自動載入更多,用throttle來判斷;
2.3 實作
還是上述列子,這裡加入節流來優化一下,完整程式碼如下:
nbsp;html> <meta> <title>加入节流</title> <style></style> <script> window.onload = function () { //模拟ajax请求 function ajax(content) { console.log('ajax request ' + content) } function throttle(fun, delay) { let last, deferTimer return function (args) { let that = this; let _args = arguments; let now = +new Date(); if (last && now < last + delay) { clearTimeout(deferTimer); deferTimer = setTimeout(function () { last = now; fun.apply(that, _args); }, delay) } else { last = now; fun.apply(that, _args); } } } let throttleAjax = throttle(ajax, 1000) let inputThrottle = document.getElementById('throttle') inputThrottle.addEventListener('keyup', function (e) { throttleAjax(e.target.value) }) } </script> <div> 3.加入节流后的输入: <input> </div>
效果:實驗可發現在持續輸入時,會安裝程式碼中的設定,每1秒執行一次ajax請求
#加入節流
#3. 小結
總結下防手震與節流的差異:
-- 效果:
函數防手震是某一段時間內只執行一次;而函數節流是間隔時間執行,不管事件觸發有多頻繁,都會保證在規定時間內一定會執行一次真正的事件處理函數。
-- 原理:
防手震是維護一個計時器,規定在delay時間後觸發函數,但是在delay時間內再次觸發的話,都會清除當前的timer 然後重新設定超時調用,即重新計時。這樣一來,只有最後一次操作能被觸發。
節流是透過判斷是否到達一定時間來觸發函數,若沒到規定時間則使用計時器延遲,而下一次事件則會重新設定計時器。
#以上是JavaScript防手震和節流的應用以及實作方法介紹(程式碼範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!