淺談JavaScript節(jié)流與防抖
節(jié)流與防抖
背景:當我們頻繁去請求資源、接口等其他的時候,就會造成操作Dom頻繁,接口壓力大等等,性能下降。比如我有時候會每次搜索會猛地敲回車,在網(wǎng)絡不很好的時候,點擊下一頁按鈕的時候也會一直點,可能網(wǎng)絡不好也可能服務器性能低。
為了避免頻繁觸發(fā)同一事件或請求,這時候就要用到節(jié)流和防抖了。
what?這是啥?當我第一次聽到這兩個名字的時候,心想是指節(jié)省流量、防止手抖嗎。百思不得其解,趕緊就去學習。
概念:
簡單來說:節(jié)流和防抖就是為了防止事件在短時間內(nèi)多次觸發(fā)的兩種解決方案。都是用過減少請求的次數(shù),來降低壓力,提高性能。
區(qū)別
節(jié)流:在一定的時間內(nèi)只會請求一次。
可以理解為:公交車,每個人是一次點擊請求,每十分鐘開一趟車,發(fā)送請求
防抖:觸發(fā)事件后n秒后才能執(zhí)行函數(shù),如果在n秒內(nèi)觸發(fā)了事件,則會重新計算執(zhí)行時間。
比如在一段時間內(nèi),我一直點擊按鈕,以最后一次點擊為準發(fā)送一次請求。
節(jié)流實現(xiàn)
解決思路 :
使用時間戳(發(fā)生在一段時間的開始),就是在計算
當前點擊的時間 - 上一次執(zhí)行函數(shù)的時間 > 我設定的時間戳 ,就執(zhí)行一次函數(shù)
缺點:第一次直接觸發(fā) 最后一次一段時間內(nèi)無法觸發(fā)
給一個場景,當我們搜索數(shù)據(jù)的時候,發(fā)起請求,沒有做處理是這樣的,請求肯定太過于頻繁

節(jié)流函數(shù)
代碼:
<body>
<div>
<span>節(jié)流處理</span><input id="input" type="text">
<button id="btn">請求</button>
</div>
</body>
<script>
var btn = document.getElementById("btn")
btn.addEventListener("click", throttle(output, 1000)) //添加點擊事件監(jiān)聽
function output(e) {
console.log(this, e)
console.log(document.getElementById("input").value) //模擬發(fā)起一次請求
}
//節(jié)流函數(shù)
function throttle(fn, delay) { // fn為執(zhí)行的函數(shù),delay為延遲時間
var last = 0; //上一次結(jié)束的時間
return function () {
var cur = Date.now()
console.log(cur-last)
if (cur - last > delay) {
fn.apply(this, arguments) //執(zhí)行函數(shù)
last = cur //更新上一次時間
}
}
}
</script>
效果:

防抖實現(xiàn)
解決思路 :
定時器(發(fā)生在定時結(jié)束)。缺點:第一次不觸發(fā) 最后一次延遲觸發(fā)
就是設置一個定時器,如果一直點擊則清除定時器,最后一次開啟定時器
防抖函數(shù)
代碼:
<body>
<div>
<span>防抖處理</span><input id="input" type="text">
<button id="btn">請求</button>
</div>
</body>
<script>
var btn = document.getElementById("btn")
btn.addEventListener("click", debounce(output, 1000)) //添加點擊事件監(jiān)聽
function output(e) {
console.log(this, e)
console.log(document.getElementById("input").value) //模擬發(fā)起一次請求
}
function debounce(fn, delay) { // fn為執(zhí)行的函數(shù),delay為延遲時間
var time = null; //定時器
return function () {
clearTimeout(time); //清除定時器
let context = this; //獲取當前button上下文 如果不指定,箭頭函數(shù)就會一直往外找到window
let args = arguments;
time = setTimeout(() => {
fn.apply(context, args);
}, delay);
}
}
</script>
效果:

防抖升級版
第一次觸發(fā)和最后一次延遲觸發(fā)
代碼:
function throttle(fn, delay) { // fn為執(zhí)行的函數(shù),delay為延遲時間
let time = null
let flag=true //標識是不是第一次觸發(fā)
return function () {
clearTimeout(time)
if (flag) {
fn.apply(this, arguments)
flag=false
}
time = setTimeout(() => { //觸發(fā)定時器
fn.apply(this, arguments)
flag=true
}, delay)
}
}
效果:

總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
節(jié)流與防抖
背景:當我們頻繁去請求資源、接口等其他的時候,就會造成操作Dom頻繁,接口壓力大等等,性能下降。比如我有時候會每次搜索會猛地敲回車,在網(wǎng)絡不很好的時候,點擊下一頁按鈕的時候也會一直點,可能網(wǎng)絡不好也可能服務器性能低。
為了避免頻繁觸發(fā)同一事件或請求,這時候就要用到節(jié)流和防抖了。
what?這是啥?當我第一次聽到這兩個名字的時候,心想是指節(jié)省流量、防止手抖嗎。百思不得其解,趕緊就去學習。
概念:
簡單來說:節(jié)流和防抖就是為了防止事件在短時間內(nèi)多次觸發(fā)的兩種解決方案。都是用過減少請求的次數(shù),來降低壓力,提高性能。
區(qū)別
節(jié)流:在一定的時間內(nèi)只會請求一次。
可以理解為:公交車,每個人是一次點擊請求,每十分鐘開一趟車,發(fā)送請求
防抖:觸發(fā)事件后n秒后才能執(zhí)行函數(shù),如果在n秒內(nèi)觸發(fā)了事件,則會重新計算執(zhí)行時間。
比如在一段時間內(nèi),我一直點擊按鈕,以最后一次點擊為準發(fā)送一次請求。
節(jié)流實現(xiàn)
解決思路 :
使用時間戳(發(fā)生在一段時間的開始),就是在計算
當前點擊的時間 - 上一次執(zhí)行函數(shù)的時間 > 我設定的時間戳 ,就執(zhí)行一次函數(shù)
缺點:第一次直接觸發(fā) 最后一次一段時間內(nèi)無法觸發(fā)
給一個場景,當我們搜索數(shù)據(jù)的時候,發(fā)起請求,沒有做處理是這樣的,請求肯定太過于頻繁

節(jié)流函數(shù)
代碼:
<body>
<div>
<span>節(jié)流處理</span><input id="input" type="text">
<button id="btn">請求</button>
</div>
</body>
<script>
var btn = document.getElementById("btn")
btn.addEventListener("click", throttle(output, 1000)) //添加點擊事件監(jiān)聽
function output(e) {
console.log(this, e)
console.log(document.getElementById("input").value) //模擬發(fā)起一次請求
}
//節(jié)流函數(shù)
function throttle(fn, delay) { // fn為執(zhí)行的函數(shù),delay為延遲時間
var last = 0; //上一次結(jié)束的時間
return function () {
var cur = Date.now()
console.log(cur-last)
if (cur - last > delay) {
fn.apply(this, arguments) //執(zhí)行函數(shù)
last = cur //更新上一次時間
}
}
}
</script>
效果:

防抖實現(xiàn)
解決思路 :
定時器(發(fā)生在定時結(jié)束)。缺點:第一次不觸發(fā) 最后一次延遲觸發(fā)
就是設置一個定時器,如果一直點擊則清除定時器,最后一次開啟定時器
防抖函數(shù)
代碼:
<body>
<div>
<span>防抖處理</span><input id="input" type="text">
<button id="btn">請求</button>
</div>
</body>
<script>
var btn = document.getElementById("btn")
btn.addEventListener("click", debounce(output, 1000)) //添加點擊事件監(jiān)聽
function output(e) {
console.log(this, e)
console.log(document.getElementById("input").value) //模擬發(fā)起一次請求
}
function debounce(fn, delay) { // fn為執(zhí)行的函數(shù),delay為延遲時間
var time = null; //定時器
return function () {
clearTimeout(time); //清除定時器
let context = this; //獲取當前button上下文 如果不指定,箭頭函數(shù)就會一直往外找到window
let args = arguments;
time = setTimeout(() => {
fn.apply(context, args);
}, delay);
}
}
</script>
效果:

防抖升級版
第一次觸發(fā)和最后一次延遲觸發(fā)
代碼:
function throttle(fn, delay) { // fn為執(zhí)行的函數(shù),delay為延遲時間
let time = null
let flag=true //標識是不是第一次觸發(fā)
return function () {
clearTimeout(time)
if (flag) {
fn.apply(this, arguments)
flag=false
}
time = setTimeout(() => { //觸發(fā)定時器
fn.apply(this, arguments)
flag=true
}, delay)
}
}
效果:

總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
- JavaScript函數(shù)防抖動debounce
- 通過實例講解JS如何防抖動
- JavaScript運動框架 解決防抖動問題、懸浮對聯(lián)(二)
- JavaScript中防抖和節(jié)流的區(qū)別及適用場景
- JavaScript中防抖和節(jié)流的實戰(zhàn)應用記錄
- JavaScript深入理解節(jié)流與防抖
- JavaScript防抖與節(jié)流的實現(xiàn)與注意事項
- JavaScript的防抖和節(jié)流一起來了解下
- JavaScript中函數(shù)的防抖與節(jié)流詳解
- javascript的防抖和節(jié)流你了解嗎
- 關(guān)于JavaScript防抖與節(jié)流的區(qū)別與實現(xiàn)
- JavaScript防抖與節(jié)流詳解
- JavaScript 防抖和節(jié)流詳解
- JavaScript防抖動與節(jié)流處理
相關(guān)文章
javascript + jquery實現(xiàn)定時修改文章標題
用javascript+jquery寫的一個定時器,定時修改文章標題,需要的朋友可以參考下2014-03-03

