摘要:防抖和節(jié)流連續(xù)觸發(fā)觸發(fā)頻率很高的時間,不進行優(yōu)化,會出現(xiàn)頁面卡頓現(xiàn)象。節(jié)流防抖是多次觸發(fā)事件,目標函數(shù)只執(zhí)行一次,不管觸發(fā)這些事件用了多少時間。
防抖(debounce)和節(jié)流(throttle)
連續(xù)觸發(fā)(觸發(fā)頻率很高)的時間,不進行優(yōu)化,會出現(xiàn)頁面卡頓現(xiàn)象。
常見的需要優(yōu)化的事件:
鼠標事件:
mousemove(拖拽)
mouseover(劃過)
mouseWheel(滾屏)
鍵盤事件:
keydown(按下鍵盤)
keypress(按下字符鍵盤)
keyup(彈起鍵盤)
window resize/scroll
DOM 元素動態(tài)定位
優(yōu)化方式是控制事件處理器在一段時間內(nèi)的執(zhí)行次。
防抖頻繁(連續(xù))觸發(fā)事件(比如用戶觸發(fā)輸入事件input),不執(zhí)行目標動作,當不在觸發(fā)事件了,再執(zhí)行。
實現(xiàn)思路,在事件處理器內(nèi),使用 setTimeout 包裹目標動作,一直觸發(fā)事件,就清除上次的定時器,不再觸發(fā)觸發(fā)事件,會執(zhí)行最后一個定時器,目標動作也執(zhí)行一次了。
JS代碼:
function debounce(callback, delay) { let timeout = 0; return e => { console.log("清除", timeout, new Date()); clearTimeout(timeout); //input 一直觸發(fā),就清除上一次的定時器,防止執(zhí)行目標函數(shù),直到事件不觸發(fā)事件,最后一個定時器沒有清除,delay 時間后就會執(zhí)定時器,就確保了目標函數(shù)只執(zhí)行一次。 timeout = setTimeout(() => { callback(e); }, delay); console.log("新的", timeout, e.target.value, new Date()); }; } let print = debounce(e => { let value = e.target.value; console.log(value, new Date()); }, 1000); document .querySelector("#input") .addEventListener("input", print, false);
清除定時器的時機很關(guān)鍵,在新定時器生成之前,如果在之后,會將所有定時器都清除,目標函數(shù)一次都不執(zhí)行。
節(jié)流防抖是多次觸發(fā)事件,目標函數(shù)只執(zhí)行一次,不管觸發(fā)這些事件用了多少時間。而節(jié)流是在一段時間內(nèi),確保目標函數(shù)只執(zhí)行一次,實現(xiàn)緩慢執(zhí)行目標函數(shù)的效果。
上面的輸入使用節(jié)流實現(xiàn):
let thorttle = (callback, delay) => { let timeout = 0; let now = new Date() - 0; return e => { console.log("now", now); let last = new Date() - 0; clearTimeout(timeout); if (last - now >= delay) { console.log("時間間隔", last - now); callback(e); now = last;//將上執(zhí)行的時間賦值給 now } else { //將 delay 時間內(nèi)多次觸發(fā)事件,目標函數(shù)合并到這里執(zhí)行 timeout = setTimeout(() => { callback(e); }, delay); } }; }; let write = thorttle(e => { console.log(e.target.value, new Date()); }, 5000); document .querySelector("#input") .addEventListener("input", write, false);兩者比較
節(jié)流在某個時間段內(nèi),目標函數(shù)能執(zhí)行一次,限制目標函數(shù)的執(zhí)行頻率,不管事件觸發(fā)了多少次;
防抖是多次觸發(fā)事件,目標函數(shù)只執(zhí)行一次,不管觸發(fā)了這些事件用了多少時間。
節(jié)流函數(shù)限制目標函數(shù)的執(zhí)行頻率,有連續(xù)變化的效果,適用于關(guān)注變化過程的操作,可以調(diào)整目標函數(shù)執(zhí)行頻率使得變化更加平滑,比如動畫、改變窗口時執(zhí)行某些操作等,常用事件resize、scroll、mouseWheel、touchmove、mouseover等;
防抖函數(shù)適用于更關(guān)注結(jié)果的操作,不太關(guān)注操作過程,常見的事件有 input、keyup等。
最后看一個 將 防抖 和 節(jié)流都用 resize 事件的效果,更能體會兩者的區(qū)別:
function debounce(callback, delay) { let timeout = 0; return e => { clearTimeout(timeout); timeout = setTimeout(() => { callback(e); }, delay); }; } let print = debounce(e => { let value = e.target.value; console.log("debounce", window.innerWidth); }, 500); let thorttle = (callback, delay) => { let timeout = 0; let now = new Date() - 0; return e => { let last = new Date() - 0; clearTimeout(timeout); if (last - now >= delay) { callback(e); now = last; } else { timeout = setTimeout(() => { callback(e); }, delay); } }; }; let write = thorttle(e => { console.log("thorttle", window.innerWidth); }, 500); window.addEventListener("resize", write, false); window.addEventListener("resize", print, false);參考
函數(shù)節(jié)流與函數(shù)防抖
函數(shù)防抖與函數(shù)節(jié)流
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/104855.html
摘要:防抖和節(jié)流連續(xù)觸發(fā)觸發(fā)頻率很高的時間,不進行優(yōu)化,會出現(xiàn)頁面卡頓現(xiàn)象。節(jié)流防抖是多次觸發(fā)事件,目標函數(shù)只執(zhí)行一次,不管觸發(fā)這些事件用了多少時間。 防抖(debounce)和節(jié)流(throttle) 連續(xù)觸發(fā)(觸發(fā)頻率很高)的時間,不進行優(yōu)化,會出現(xiàn)頁面卡頓現(xiàn)象。常見的需要優(yōu)化的事件: 鼠標事件: mousemove(拖拽) mouseover(劃過) mouseWheel(滾屏)...
摘要:節(jié)流在指定時間之內(nèi),讓函數(shù)只觸發(fā)一次。防抖對于一定時間段的連續(xù)的函數(shù)調(diào)用,只讓其執(zhí)行一次。總結(jié)以上只是很簡單的寫了一下節(jié)流和防抖的原理,在里,實現(xiàn)起來更加復(fù)雜,但是背后的原理核心就是上邊代碼寫的。 概述 在平時的開發(fā)中,經(jīng)常會聽到兩個差不多很相近的詞。節(jié)流(throttle)和防抖(debounce)。這是兩個類似又有些不同的優(yōu)化方案。 節(jié)流:在指定時間之內(nèi),讓函數(shù)只觸發(fā)一次。 防...
摘要:防抖函數(shù)防抖和節(jié)流是一對常常被放在一起的場景。同時,這里會設(shè)置一個定時器,在等待后會執(zhí)行,的主要作用就是觸發(fā)。最后,如果不再有函數(shù)調(diào)用,就會在定時器結(jié)束時執(zhí)行。 函數(shù)節(jié)流和去抖的出現(xiàn)場景,一般都伴隨著客戶端 DOM 的事件監(jiān)聽。比如scroll resize等事件,這些事件在某些場景觸發(fā)非常頻繁。 比如,實現(xiàn)一個原生的拖拽功能(不能用 H5 Drag&Drop API),需要一路監(jiān)聽...
摘要:相反,在討論時,面試中通常會提到三件事。而認為最后一個參賽者說了算,只要還能吃的,就重新設(shè)定新的定時器。試想,如果用戶的操作十分頻繁他每次都不等設(shè)置的時間結(jié)束就進行下一次操作,于是每次都為該用戶重新生成定時器,回調(diào)函數(shù)被延遲了不計其數(shù)次。本文不是討論最新的 JavaScript 庫、常見的開發(fā)實踐或任何新的 ES6 函數(shù)。相反,在討論 JavaScript 時,面試中通常會提到三件事。我自己...
摘要:當?shù)诙握{(diào)用該函數(shù)時,它會清除前一次的定時器并設(shè)置另一個。然而,如果前一個定時器尚未執(zhí)行,其實就是將其替換為一個新的定時器,然后延遲一定時間再執(zhí)行。參考文章函數(shù)節(jié)流與函數(shù)防抖函數(shù)節(jié)流和函數(shù)去抖應(yīng)用場景辨析函數(shù)節(jié)流函數(shù)防抖實現(xiàn)原理分析 前言 事件的觸發(fā)權(quán)很多時候都屬于用戶,有些情況下會產(chǎn)生問題: 向后臺發(fā)送數(shù)據(jù),用戶頻繁觸發(fā),對服務(wù)器造成壓力 一些瀏覽器事件:window.onresi...
閱讀 2734·2021-11-22 13:52
閱讀 1202·2021-10-14 09:43
閱讀 3657·2019-08-30 15:56
閱讀 2963·2019-08-30 13:22
閱讀 3288·2019-08-30 13:10
閱讀 1574·2019-08-26 13:45
閱讀 1111·2019-08-26 11:47
閱讀 2805·2019-08-23 18:13