當(dāng)用戶在網(wǎng)頁中進(jìn)行操作時,如點擊、滾動、輸入等,往往會頻繁地觸發(fā)事件。如果每個事件都立即執(zhí)行相應(yīng)的函數(shù),可能會導(dǎo)致性能問題和用戶體驗不佳,因為這些函數(shù)可能需要執(zhí)行復(fù)雜的操作,如計算、網(wǎng)絡(luò)請求等。
為了優(yōu)化這種情況,我們可以使用防抖和節(jié)流來限制函數(shù)的調(diào)用次數(shù),從而提高性能和用戶體驗。
?文章來源地址http://www.zghlxwxcb.cn/news/detail-423492.html
防抖
防抖是指在一定的時間間隔內(nèi),將多次觸發(fā)的事件合并成一次執(zhí)行。
防抖的實現(xiàn)思路是:每次事件被觸發(fā)時,設(shè)置一個計時器,在指定的時間間隔內(nèi),如果該事件被再次觸發(fā),則清除計時器并重新開始計時,直到指定的時間間隔內(nèi)沒有事件觸發(fā)為止,然后調(diào)用函數(shù)。
?
防抖可以用于處理一些頻繁觸發(fā)的事件,如窗口大小改變、輸入框輸入等。以下是一個簡單的防抖函數(shù)實現(xiàn):
function debounce(fn, delay) { let timer; return function() { const context = this; const args = arguments; clearTimeout(timer); timer = setTimeout(function() { fn.apply(context, args); }, delay); }; }
?
這個函數(shù)接收兩個參數(shù): fn 是要防抖的函數(shù), delay 是防抖時間間隔。返回一個新的函數(shù),在防抖時間間隔內(nèi),重復(fù)調(diào)用這個新函數(shù)不會立即觸發(fā)原函數(shù),只有等時間間隔過去之后才會觸發(fā)。
?
節(jié)流
節(jié)流是指在一定的時間間隔內(nèi),函數(shù)只被調(diào)用一次。如果在這個時間間隔內(nèi)觸發(fā)了多次事件,只有第一次會調(diào)用函數(shù),其余的會被忽略。
節(jié)流的實現(xiàn)思路是:每次事件被觸發(fā)時,如果函數(shù)沒有在指定的時間間隔內(nèi)被調(diào)用過,則調(diào)用函數(shù)并設(shè)置一個計時器,在指定的時間間隔內(nèi)不再觸發(fā)事件。如果在指定的時間間隔內(nèi)再次觸發(fā)了事件,則不調(diào)用函數(shù),直到指定的時間間隔過去,重新開始調(diào)用函數(shù)。
?
節(jié)流可以用于處理一些頻繁觸發(fā)的事件,如頁面滾動、鼠標(biāo)移動等。以下是一個簡單的節(jié)流函數(shù)實現(xiàn):
function throttle(fn, delay) { let timer; return function() { const context = this; const args = arguments; if (!timer) { timer = setTimeout(function() { fn.apply(context, args); timer = null; }, delay); } }; }
這個函數(shù)接收兩個參數(shù): fn 是要節(jié)流的函數(shù), delay 是節(jié)流時間間隔。返回一個新的函數(shù),在指定的時間間隔內(nèi),只能調(diào)用一次原函數(shù)。
?
?
防抖和節(jié)流的實現(xiàn)方式可以有多種,具體實現(xiàn)應(yīng)該根據(jù)實際場景進(jìn)行調(diào)整。下面介紹一些常見的實現(xiàn)方式。
?
立即執(zhí)行版和非立即執(zhí)行版
防抖和節(jié)流的實現(xiàn)中,可以根據(jù)需求選擇立即執(zhí)行版或非立即執(zhí)行版。
立即執(zhí)行版是指在每次觸發(fā)事件時,立即執(zhí)行一次函數(shù),然后在指定的時間間隔內(nèi)不再執(zhí)行。這種方式適合處理一些需要立即響應(yīng)的事件,如按鈕點擊等。
?
以下是立即執(zhí)行版的防抖函數(shù)實現(xiàn):
function debounce(fn, delay, immediate) { let timer; return function() { const context = this; const args = arguments; if (immediate && !timer) { fn.apply(context, args); } clearTimeout(timer); timer = setTimeout(function() { if (!immediate) { fn.apply(context, args); } timer = null; }, delay); }; }
?
這個函數(shù)增加了一個參數(shù) immediate ,用來指定是否立即執(zhí)行函數(shù)。如果設(shè)置為 true ,則在觸發(fā)事件時立即執(zhí)行函數(shù);否則等待指定的時間間隔后再執(zhí)行。
?
?
非立即執(zhí)行版是指在事件停止觸發(fā)指定時間后才執(zhí)行一次函數(shù)。這種方式適合處理一些連續(xù)觸發(fā)的事件,如輸入框輸入等。
以下是非立即執(zhí)行版的防抖函數(shù)實現(xiàn):
function debounce(fn, delay, immediate) { let timer; return function() { const context = this; const args = arguments; if (timer) { clearTimeout(timer); } if (immediate && !timer) { fn.apply(context, args); } timer = setTimeout(function() { if (!immediate) { fn.apply(context, args); } timer = null; }, delay); }; }
這個函數(shù)與立即執(zhí)行版的實現(xiàn)相似,區(qū)別在于多了一個 if (timer) { clearTimeout(timer); } 判斷。如果計時器已經(jīng)存在,則在重新設(shè)置計時器之前先清除之前的計時器。
?
時間戳版和定時器版
防抖和節(jié)流的實現(xiàn)中,可以根據(jù)需求選擇時間戳版或定時器版。
時間戳版是指在事件觸發(fā)后,記錄下當(dāng)前的時間戳,并在下次事件觸發(fā)時再次記錄時間戳。在指定的時間間隔內(nèi),如果事件再次觸發(fā),則更新時間戳。如果時間戳與當(dāng)前時間的差值超過了指定的時間間隔,則執(zhí)行函數(shù)。這種方式適合處理一些需要立即響應(yīng)的事件,如按鈕點擊等。
?
以下是時間戳版的節(jié)流函數(shù)實現(xiàn):
function throttle(fn, delay) { let last = 0; return function() { const context = this; const args = arguments; const now = +new Date(); if (now - last > delay) { fn.apply(context, args); last = now; } };
這個函數(shù)中, last 記錄上次執(zhí)行函數(shù)的時間戳,每次事件觸發(fā)時,計算當(dāng)前時間戳與上次執(zhí)行函數(shù)的時間戳的差值,如果超過指定的時間間隔,則執(zhí)行函數(shù)并更新 last 。
?
?
定時器版是指在事件觸發(fā)后,設(shè)置一個定時器,在指定的時間間隔內(nèi)不再觸發(fā)事件。如果在指定的時間間隔內(nèi)再次觸發(fā)了事件,則不執(zhí)行函數(shù),直到定時器到期后再次執(zhí)行函數(shù)。這種方式適合處理一些連續(xù)觸發(fā)的事件,如頁面滾動、鼠標(biāo)移動等。
?
以下是定時器版的節(jié)流函數(shù)實現(xiàn):
function throttle(fn, delay) { let timer; return function() { const context = this; const args = arguments; if (!timer) { timer = setTimeout(function() { fn.apply(context, args); timer = null; }, delay); } }; }
這個函數(shù)與之前介紹的非立即執(zhí)行版的防抖函數(shù)實現(xiàn)類似,區(qū)別在于將 setTimeout 的時間間隔設(shè)置為指定的時間間隔,而不是事件觸發(fā)后的延遲時間。
防抖和節(jié)流的主要區(qū)別在于它們限制函數(shù)調(diào)用的方式不同。防抖是指在指定的時間間隔內(nèi)將多次觸發(fā)的事件合并成一次執(zhí)行,而節(jié)流是指在指定的時間間隔內(nèi),函數(shù)只被調(diào)用一次。同時,防抖和節(jié)流也有一些缺點,比如可能會導(dǎo)致事件響應(yīng)延遲或事件被忽略等問題。因此,在實際使用中,需要根據(jù)場景進(jìn)行權(quán)衡和選擇。 文章來源:http://www.zghlxwxcb.cn/news/detail-423492.html
?
到了這里,關(guān)于防抖和節(jié)流及多種實現(xiàn)方式的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!