在上一篇里,讲到了在滚动字母列表时绑定了函数handleTouchMove,这个函数有很大的改进空间。
handleTouchMove(e){
// 当状态等于true时才对执行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生命函数钩子初始化startY
从上面代码里可以看到,每次执行handleTouchMove函数的时候都会重新计算startY,而且handleTouchMove函数执行次数太频繁了!(不然也不会优化它)
考虑在数据更新渲染,也就是updated的时候就计算好startY,每次调用就可。
updated() {
this.startY=this.$refs["A"][0].offsetTop
},
cities在开始时是[ ],在ajax成功后才获取到数据,cities得到值后会再次渲染,此时,updated函数执行,可以得到startY
2.节流
因为函数调用的很频繁,可以定一个计时器帮助节流。
如果计时器存在,就清除计时器重新开始计数,如果没有就创建新的,这样性能会大大提高。
if(this.touchStatus){
// 节流操作
if(this.timer){
// 如果有定时器就清除
clearTimeout(this.timer)
}
// 没有 重新创建
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);
节流参考
函数节流
函数节流(throttle):当持续触发事件时,保证一定时间段内只调用一次事件处理函数。节流通俗解释就比如我们水龙头放水,阀门一打开,水哗哗的往下流,秉着勤俭节约的优良传统美德,我们要把水龙头关小点,最好是如我们心意按照一定规律在某个时间间隔内一滴一滴的往下滴。如下图,持续触发scroll事件时,并不立即执行handle函数,每隔1000毫秒才会执行一次handle函数。
函数节流主要有两种实现方法:时间戳和定时器
节流.png
当触发事件的时候,我们设置一个定时器,再次触发事件的时候,如果定时器存在,就不执行,直到delay时间后,定时器执行执行函数,并且清空定时器,这样就可以设置下个定时器。当第一次触发事件时,不会立即执行函数,而是在delay秒后才执行。而后再怎么频繁触发事件,也都是每delay时间才执行一次。当最后一次停止触发后,由于定时器的delay延迟,可能还会执行一次函数。
也就是我们规定一段时间(一个计时器内)只能触发一次事件。
