JavaScript函數(shù)節(jié)流概念與用法實例詳解
本文實例講述了JavaScript函數(shù)節(jié)流概念與用法。分享給大家供大家參考,具體如下:
最近在做網(wǎng)頁的時候有個需求,就是瀏覽器窗口改變的時候需要改一些頁面元素大小,于是乎很自然的想到了window的resize事件,于是乎我是這么寫的
<!DOCTYPE html>
<html>
<head>
<title>Throttle</title>
</head>
<body>
<script type="text/javascript">
n=0;
function resizehandler(){
console.log(new Date().getTime());
console.log(++n);
}
window.onresize=resizehandler;
</script>
</body>
</html>
功能倒是實現(xiàn)了,但是我拖拽的方式改變?yōu)g覽器窗口大小的時候看了下控制臺

沒錯,簡單的一個拖拽讓我的resizeHandler()方法執(zhí)行了52次,這完全不是我想要的效果,實際上我的resizeHandler()方法的代碼很復(fù)雜,甚至?xí)褂胊jax向服務(wù)器發(fā)送請求,要是簡單的一次改變窗口大小就要調(diào)用52次這還了得
函數(shù)節(jié)流
其實我的本意只是窗口resize后頁面做一些調(diào)整就可以,而window的resize事件并不是在resize結(jié)束后才觸發(fā)的,具體則么個頻率我也不知道,但卻是在不停的調(diào)用,直到窗口大小不再變化。其實類似的機制還有鼠標的mousemove,都是在短時間內(nèi)重復(fù)觸發(fā)。
在《JavaScript高級程序設(shè)計》中有專門應(yīng)對此問題的函數(shù)節(jié)流
function throttle(method,context){
clearTimeout(method.tId);
method.tId=setTimeout(function(){
method.call(context);
},500);
}
原理很簡單,利用定時器,讓函數(shù)執(zhí)行延遲500毫秒,在500毫秒內(nèi)如果有函數(shù)又被調(diào)用則刪除上一次調(diào)用,這次調(diào)用500毫秒后執(zhí)行,如此往復(fù)。這樣我剛才的代碼可以改為
<script type="text/javascript">
n=0;
function resizehandler(){
console.log(new Date().getTime());
console.log(++n);
}
function throttle(method,context){
clearTimeout(method.tId);
method.tId=setTimeout(function(){
method.call(context);
},500);
}
window.onresize=function(){
throttle(resizehandler,window);
};
</script>
拖拽一下試試,果真只執(zhí)行了一次

另一種做法
網(wǎng)上還有一種函數(shù)節(jié)流方案,它是這么做的
function throttle(method,delay){
var timer=null;
return function(){
var context=this, args=arguments;
clearTimeout(timer);
timer=setTimeout(function(){
method.apply(context,args);
},delay);
}
}
調(diào)用一下試試,一樣的效果
<script type="text/javascript">
n=0;
function resizehandler(){
console.log(new Date().getTime());
console.log(++n);
}
function throttle(method,delay){
var timer=null;
return function(){
var context=this, args=arguments;
clearTimeout(timer);
timer=setTimeout(function(){
method.apply(context,args);
},delay);
}
}
window.onresize=throttle(resizehandler,500);//因為返回函數(shù)句柄,不用包裝函數(shù)了
</script>

比較
兩種方法都是利用了setTimeout,不同的是第二種方法加入的函數(shù)延遲執(zhí)行時間,這個在第一種方案中很容易也具有此功能,加一個參數(shù)的事兒。
但第一種方案把tId設(shè)為函數(shù)的一個變量保存,而第二種創(chuàng)建了一個閉包來存儲。個人覺得差距不大,很喜歡第一種,簡單,高效。
新需求
有一天做了個類似的東西,就像百度首頁輸入自動提示一樣的東西,我在text上綁定keyup事件,每次鍵盤彈起的時候自動提示,但是又不想提示那么頻繁,于是我用了上面方法,但是悲劇了,只有停止輸入等500毫秒才會提示,在輸入過程中根本就沒有提示??戳艘幌麓a,可不是嘛,只要是用戶會盲打,在500毫秒內(nèi)按一下鍵盤,提示函數(shù)就會不斷被延遲,這樣只有停下來的時候才會提示,這就沒意義了。
能不能在函數(shù)節(jié)流的基礎(chǔ)上間隔固定時間就執(zhí)行一次?
小改動
在網(wǎng)上搜了一下我們可以根據(jù)第二種寫法(第一種為函數(shù)拓展多個變量感覺有些不好)做些改動,添加一個參數(shù)作為到固定間隔必須執(zhí)行
function throttle(method,delay,duration){
var timer=null, begin=new Date();
return function(){
var context=this, args=arguments, current=new Date();;
clearTimeout(timer);
if(current-begin>=duration){
method.apply(context,args);
begin=current;
}else{
timer=setTimeout(function(){
method.apply(context,args);
},delay);
}
}
}
這樣每次我們判斷間隔了多久,要是超過設(shè)置時間則立即執(zhí)行一次,以剛才例子試一試效果
window.onresize=throttle(resizehandler,100,200);

果真既沒有頻繁執(zhí)行也沒有就最后執(zhí)行
更多關(guān)于JavaScript相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《JavaScript切換特效與技巧總結(jié)》、《JavaScript查找算法技巧總結(jié)》、《JavaScript動畫特效與技巧匯總》、《JavaScript錯誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》、《JavaScript遍歷算法與技巧總結(jié)》及《JavaScript數(shù)學(xué)運算用法總結(jié)》
希望本文所述對大家JavaScript程序設(shè)計有所幫助。
- JS函數(shù)節(jié)流和函數(shù)防抖問題分析
- JavaScript函數(shù)節(jié)流和函數(shù)防抖之間的區(qū)別
- 淺析JavaScript 函數(shù)防抖和節(jié)流
- 詳解JS函數(shù)防抖
- 如何解決js函數(shù)防抖、節(jié)流出現(xiàn)的問題
- JavaScript性能優(yōu)化之函數(shù)節(jié)流(throttle)與函數(shù)去抖(debounce)
- JS中setTimeout的巧妙用法前端函數(shù)節(jié)流
- 淺談JavaScript函數(shù)節(jié)流
- 如何理解JS函數(shù)防抖和函數(shù)節(jié)流
相關(guān)文章
JavaScript中EventBus實現(xiàn)對象之間通信
這篇文章主要介紹了JavaScript中EventBus實現(xiàn)對象之間通信,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10
一文詳解Web Audio瀏覽器采集麥克風音頻數(shù)據(jù)
這篇文章主要為大家介紹Web Audio瀏覽器采集麥克風音頻數(shù)據(jù)實現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-03-03
詳解JavaScript如何控制并發(fā)請求數(shù)量
某些情況下,我們可能需要對需要執(zhí)行的多個異步任務(wù)進行異步數(shù)量控制,只允許固定數(shù)量的任務(wù)執(zhí)行,本文為大家整理了JS控制并發(fā)請求數(shù)量的相關(guān)代碼,希望對大家有所幫助2024-01-01
滾動條響應(yīng)鼠標滑輪事件實現(xiàn)上下滾動的js代碼
javascript實現(xiàn)滾動條響應(yīng)鼠標滑輪的實現(xiàn)上下滾動,示例代碼如下2014-06-06
JavaScript金額運算出現(xiàn)精度丟失問題的解決方案
在 JavaScript 中,浮點數(shù)運算可能會產(chǎn)生精度丟失的問題,尤其在處理 金額計算 時,本文為大家整理了一些常用方法,有需要的小伙伴可以根據(jù)需求進行選擇2025-03-03

