小程式倒數計時重疊抖動問題
因為請求資料寫在onShow 函式裡面,所以每次切換介面都會重新整理,這就會導致,如果當前 定時器在跑的話,再次重新整理會再次常見定時, 那麼就會導致重新整理幾次有幾個定時器,同時在跑,那麼前端介面顯示的計時數字 就會不時跳動,所以需要保證在跑的定時器只有一個。將定時器物件建立為全域性的,在每次開啟定時器的時候先清空之前的定時器。就可以解決重新整理後計時閃動的問題了,或者在在tab頁面,運用 onHide 週期 進行 clearTimeInterval清空 , 在 非tab頁面,運用onUload() 週期 進行 clearTimeInterval清空,百度都可以找到類似解決方案,其中在我的歷史文章小程式實戰踩坑之B2B商城專案總結也有總結,程式碼類似如下:
/**
* 清除interval
* @param that
*/
clearTimeInterval: function (that) {
var interval = that.data.interval;
clearInterval(interval)
},
/**
* 生命週期函式--監聽頁面解除安裝
* 退出本頁面時停止計時器
*/
onUnload:function () {
var that = this;
that.clearTimeInterval(that)
},
/**
* 生命週期函式--監聽頁面隱藏
* 在後臺執行時停止計時器
*/
onHide:function () {
var that = this;
that.clearTimeInterval(that)
}
複製程式碼
倒數計時使用setInterval或setTimeout觸控螢幕導致時間顯示的突跳,突慢問題,卡頓,甚至停止
不信的同學,可以嘗試用手指觸控螢幕,上下小幅上下移動不放,你會發覺時間竟然停止了。(特別是針對低端機型)
通常同學寫程式碼都會如此:
let self = this;
let lefttimeSec = time - new Date().getTime();
let calc = setInterval(function() {
lefttimeSec -= 1000;
self.endtimestr = '距離拼單結束還有' + self.dateformat(lefttimeSec);
self.$apply();
if (lefttimeSec <= 0) {
clearInterval(calc);
}
}, 1000);
複製程式碼
使用setInterval後,即使用了上面說的“小程式倒數計時重疊抖動問題”解決方案,只是解決了倒數計時重疊問題,這樣寫法,會導致的一些精準度不高。其實很簡單,解決程式碼如下:
showCountTime(time){
let self = this;
setTimeout(function(){
let lefttimeSec = time - new Date().getTime();
lefttimeSec -= 1000;
self.endtimestr = '距離拼單結束還有' + self.dateformat(lefttimeSec);
self.$apply();
self.showCountTime(time);
},1000);
}
複製程式碼
注意,這裡用了setTimeout,要tab頁面,運用onHide週期進行clearTimeout清空, 在非tab頁面,運用onUload()週期 進行clearTimeout清空定時器。這步必須要做,就不多說了,要不還是會出現上面說的“小程式倒數計時重疊抖動問題”問題。
用了上面程式碼,補失的精準度不足。小心的測試同學會發現觸控螢幕導致的突跳,突慢問題,甚至停止!於是各種尋思,去找了拼多多小程式,京東購物小程式各種對比。 結論是拼多多存在和我一樣的問題,京東購物小程式的倒數計時沒這樣的問題,給個贊!
出現問題環境描述:
- 小程式框架:wepy : "^1.7.2"
- 測試機型:紅米3
自身思路是wepy髒檢查在觸控(滾動)螢幕下引起效能佔用導致的一些效率不足問題,做了進一步測試,還是用紅米3機型,拋掉元件,拋掉data,只保留data,做一個簡單的渲染,將頁面高度固定,讓螢幕可以上下滑動,程式碼如下:
<style>
.content {
height: 2000rpx;
border: 1rpx solid red;
}
.child {
height: 500rpx;
}
</style>
<template>
<view class="content">
<view class="child"></view>
{{endtimestr}}
</view>
</template>
<script>
import wepy from 'wepy';
export default class test extends wepy.page {
data = {
endtimestr: ''
}
showCountTime(time) {
let self = this;
setTimeout(function() {
let lefttimeSec = time - new Date().getTime();
lefttimeSec -= 1000;
self.endtimestr = '距離拼單結束還有' + self.dateformat(lefttimeSec);
self.$apply();
self.showCountTime(time);
}, 1000);
}
dateformat = (micro_second) => {
// 總秒數
var second = Math.floor(micro_second / 1000);
// 天數
var day = Math.floor(second / 3600 / 24);
// 小時
var hr = Math.floor(second / 3600 % 24);
// 分鐘
var min = Math.floor(second / 60 % 60);
// 秒
var sec = Math.floor(second % 60);
hr = hr < 10 ? '0' + hr : hr;
min = min < 10 ? '0' + min : min;
sec = sec < 10 ? '0' + sec : sec;
if (day > 0) {
return day + " 天" + ' ' + hr + ":" + min + ":" + sec;
} else {
return hr + ":" + min + ":" + sec;
}
}
onLoad() {
//api模擬得到time
this.showCountTime(1545899950167);
}
}
</script>
複製程式碼
結論是: 倒數計時在觸控(滾動)情況下正常了!!!那也表明wepy的髒檢查存在一些效能的不足呀,希望未來wepy有改進!