某些操作會(huì)導(dǎo)致 DOM 事件頻繁被觸發(fā),從而頻繁調(diào)用事件監(jiān)聽(tīng)函數(shù)入客,如果事件監(jiān)聽(tīng)函數(shù)中執(zhí)行的是 DOM 操作或加載資源等比較耗費(fèi)計(jì)算機(jī)資源的任務(wù)時(shí),會(huì)導(dǎo)致瀏覽器反應(yīng)遲鈍甚至崩潰。throttle 函數(shù)與 debounce 函數(shù)通過(guò)使用一些技巧疤估,減少監(jiān)聽(tīng)函數(shù)的執(zhí)行頻率,適用于瀏覽器的 resize霎冯、scroll 事件以及通過(guò)文本框 keyup 事件進(jìn)行 Ajax 請(qǐng)求等操作铃拇。
throttle 函數(shù)
throttle 函數(shù)又稱(chēng)為節(jié)流函數(shù)。我們可以把水滴理解成事件監(jiān)聽(tīng)函數(shù)沈撞,如果我們打開(kāi)水龍頭慷荔,水滴會(huì)連續(xù)不斷地涌出,就相當(dāng)于事件監(jiān)聽(tīng)函數(shù)會(huì)連續(xù)不斷地執(zhí)行缠俺。如果我們將水龍頭擰到最小显晶,讓水滴一滴一滴地流出贷岸,就相當(dāng)于我們讓事件監(jiān)聽(tīng)函數(shù)按照一定的時(shí)間間隔來(lái)執(zhí)行。
function throttle (func, wait) {
var lastInvokeTime = 0
return function () {
var time = Date.now()
if (time - lastInvokeTime >= wait) {
func()
lastInvokeTime = time
}
}
}
// handler 是事件監(jiān)聽(tīng)函數(shù)
var handler = function () {
console.log('throttle')
}
window.onscroll = throttle(handler, 300)
以上代碼中磷雇,當(dāng)連續(xù)觸發(fā) window 的 scroll 事件的時(shí)候偿警,不會(huì)連續(xù)調(diào)用 handler 函數(shù),會(huì)保證 handler 函數(shù)連續(xù)調(diào)用的最小時(shí)間間隔為 300 毫秒唯笙。
debounce 函數(shù)
debounce 函數(shù)又稱(chēng)為防抖動(dòng)函數(shù)螟蒸。我們可以把拍照理解成事件監(jiān)聽(tīng)函數(shù),當(dāng)我們按下快門(mén)的時(shí)候睁本,手可能在抖動(dòng)尿庐,這時(shí)候照相機(jī)不會(huì)立即拍照,它會(huì)等待我們的手停止抖動(dòng)之后再拍照呢堰,就相當(dāng)于當(dāng)我們連續(xù)觸發(fā)事件的時(shí)候抄瑟,事件監(jiān)聽(tīng)函數(shù)不會(huì)立即執(zhí)行,而是等我們一段時(shí)間內(nèi)不再觸發(fā)事件的時(shí)候枉疼,再執(zhí)行事件監(jiān)聽(tīng)函數(shù)皮假。
function debounce (func, wait) {
var timer = null
return function () {
clearTimeout(timer)
timer = setTimeout(func, wait)
}
}
// handler 是事件監(jiān)聽(tīng)函數(shù)
var handler = function () {
console.log('debounce')
}
window.onscroll = debounce(handler, 300)
以上代碼中,當(dāng)連續(xù)觸發(fā) window 的 scroll 事件的時(shí)候骂维,不會(huì)連續(xù)調(diào)用 handler 函數(shù)惹资,會(huì)等到持續(xù) 300 毫秒都沒(méi)有 scroll 事件觸發(fā)的時(shí)候,才調(diào)用 handler 函數(shù)航闺。