講在前面
進騰訊快半個多月了肮街,說實話在這半個多月里見識了許多新的東西风题,比如VR,AR,WebGL沛硅,AI技術等等眼刃。作為技術男的我對此十分感興趣,連玩了八年的DNF都放棄了摇肌,這需要多么大的勇氣和決心鸟整。廢話不多說了,想寫這邊文章是因為今天做項目的過程中遇到一個坑朦蕴,其實以前就遇到過篮条,只是沒有好好總結下,這個問題就是如何優(yōu)化window的resize和scroll事件吩抓。就算工作在忙涉茧,我覺得都要學會總結,總結也是一個學習和提升的過程疹娶。
問題引申
其實我們可以將這個問題進行擴大伴栓,不僅僅局限于window的scroll和resize事件,由它引申出來的問題是我們?nèi)绾谓鉀Q讓一個函數(shù)不頻繁的觸發(fā)雨饺。
解決辦法
目前業(yè)界對于這個問題有兩種不同的方法钳垮,一個是函數(shù)節(jié)流(throttle),另外一個就是函數(shù)去抖(debounce)额港。
函數(shù)節(jié)流
函數(shù)節(jié)流:就是函數(shù)按照一個周期執(zhí)行饺窿,例如給window綁定一個resize事件之后,只要window大小改變就打印1移斩,如果不采用函數(shù)節(jié)流肚医,當我們將窗口調(diào)節(jié)的時候發(fā)現(xiàn)控制臺一直打印1,但是使用了函數(shù)節(jié)流后我們會發(fā)現(xiàn)調(diào)節(jié)的過程中向瓷,每隔一段時間才打印1肠套。
下面是函數(shù)節(jié)流的簡單實現(xiàn)。
var throttle = function(delay, cb) {
var startTime = Date.now();
return function() {
var currTime = Date.now();
if (currTime - startTime > delay) {
cb();
startTime = currTime;
}
}
}
函數(shù)去抖
函數(shù)去抖:就是當事件觸發(fā)之后猖任,必須等待某一個時間之后你稚,回調(diào)函數(shù)才會執(zhí)行,假若再等待的時間內(nèi)朱躺,事件又觸發(fā)了則等待時間刷新刁赖。還是上面那個例子,如果我們一直改變窗口大小室琢,則不會打印1乾闰,只有當我們停止改變窗口大小并等待一段時間后,才會打印1盈滴。
下面是函數(shù)去抖的簡單實現(xiàn)。
var debounce = function(delay, cb) {
var timer;
return function() {
if (timer) clearTimeout(timer);
timer = setTimeout(function() {
cb();
}, delay);
}
}
最后
其實以上這兩個的思想還蠻好理解的,兩種方法均使用了閉包(緩存變量)巢钓,但是這是簡單的實現(xiàn)病苗。
目前l(fā)odash和underscore這兩個現(xiàn)成的js庫都對以上方法進行了實現(xiàn),而且封裝的更好症汹,功能更完善硫朦,有興趣的同學可以閱讀下它的源碼,我抽時間也會去閱讀一下的背镇。最后希望大家再前端的道路上越走越遠咬展。