在上一篇里浊伙,講到了在滾動字母列表時綁定了函數(shù)handleTouchMove
样漆,這個函數(shù)有很大的改進(jìn)空間为障。
handleTouchMove(e){
// 當(dāng)狀態(tài)等于true時才對執(zhí)行move事件
if(this.touchStatus){
const startY=this.$refs["A"][0].offsetTop //dom元素
const touchY= e.touches[0].clientY-80
const index=Math.floor((touchY-startY)/20)
if(index >= 0 && index < this.letters.length){
this.$emit("change",this.letters[index])
}
}
1.用updated生命函數(shù)鉤子初始化startY
從上面代碼里可以看到,每次執(zhí)行handleTouchMove函數(shù)
的時候都會重新計算startY放祟,而且handleTouchMove函數(shù)執(zhí)行次數(shù)太頻繁了w⒃埂(不然也不會優(yōu)化它)
考慮在數(shù)據(jù)更新渲染,也就是updated的時候就計算好startY跪妥,每次調(diào)用就可鞋喇。
updated() {
this.startY=this.$refs["A"][0].offsetTop
},
cities在開始時是[ ],在ajax成功后才獲取到數(shù)據(jù)眉撵,cities得到值后會再次渲染侦香,此時,updated函數(shù)執(zhí)行纽疟,可以得到startY
2.節(jié)流
因為函數(shù)調(diào)用的很頻繁罐韩,可以定一個計時器幫助節(jié)流。
如果計時器存在污朽,就清除計時器重新開始計數(shù)伴逸,如果沒有就創(chuàng)建新的,這樣性能會大大提高。
if(this.touchStatus){
// 節(jié)流操作
if(this.timer){
// 如果有定時器就清除
clearTimeout(this.timer)
}
// 沒有 重新創(chuàng)建
this.timer=setTimeout(() => {
const touchY= e.touches[0].clientY-80
const index=Math.floor((touchY-this.startY)/20)
if(index >= 0 && index < this.letters.length){
this.$emit("change",this.letters[index])
}
}, 16);
節(jié)流參考
函數(shù)節(jié)流
函數(shù)節(jié)流(throttle):當(dāng)持續(xù)觸發(fā)事件時错蝴,保證一定時間段內(nèi)只調(diào)用一次事件處理函數(shù)。節(jié)流通俗解釋就比如我們水龍頭放水颓芭,閥門一打開,水嘩嘩的往下流,秉著勤儉節(jié)約的優(yōu)良傳統(tǒng)美德凰慈,我們要把水龍頭關(guān)小點(diǎn)引瀑,最好是如我們心意按照一定規(guī)律在某個時間間隔內(nèi)一滴一滴的往下滴。如下圖州藕,持續(xù)觸發(fā)scroll事件時束世,并不立即執(zhí)行handle函數(shù),每隔1000毫秒才會執(zhí)行一次handle函數(shù)床玻。
函數(shù)節(jié)流主要有兩種實(shí)現(xiàn)方法:時間戳和定時器
當(dāng)觸發(fā)事件的時候毁涉,我們設(shè)置一個定時器,再次觸發(fā)事件的時候锈死,如果定時器存在贫堰,就不執(zhí)行,直到delay時間后待牵,定時器執(zhí)行執(zhí)行函數(shù)其屏,并且清空定時器,這樣就可以設(shè)置下個定時器缨该。當(dāng)?shù)谝淮斡|發(fā)事件時偎行,不會立即執(zhí)行函數(shù),而是在delay秒后才執(zhí)行贰拿。而后再怎么頻繁觸發(fā)事件蛤袒,也都是每delay時間才執(zhí)行一次。當(dāng)最后一次停止觸發(fā)后壮不,由于定時器的delay延遲汗盘,可能還會執(zhí)行一次函數(shù)。
也就是我們規(guī)定一段時間(一個計時器內(nèi))只能觸發(fā)一次事件询一。