swiper輪播圖息屏一段時間或快速滑動切換時出現瘋狂抖動
以前做小程序項目的時候,沒專門測試人員,都是開發者自測,可能我的手機性能比較不錯(哈哈)或時機不對,總之沒發掘到這個bug;近期做項目,測試了不同的手機,發現在一些手機上會出現這個bug,尤其是對於性能差的一些手機,出現的概率尤其的大。由於本次項目是基於uni-app的,直接就用uni-app進行操作說明;
說明:uni-app編寫小程序:采用的是微信小程序的API,Vue的語法,所以,他們很相似,只是在寫法上有一點稍微的區別,小程序的那套東西也是適用於uni-app的。
在微信小程序的官方文檔中,有這樣個提示, 如果在 bindchange 的事件回調函數中使用 setData 改變 current 值,則有可能導致 setData 被不停地調用。
最終產生的后果是如果快速滑動或者息屏一段時間打開后,就出現輪播圖的瘋狂抖動。
一、解決方法是:
在動畫播放結束后(@animationfinish)改變current的值,而不是一滑動(@change)就改變current的值。即用@animationfinish代替 @change。
二、@change與@animationfinish對比說明
1、相同點:都會改變current的值,current代表當前所在滑塊的index
2、不同點:改變current的時機不同,@change滑動時立即改變,@animationfinish動畫結束后改變!
三、說明:
如果想要自定義面板指示點,不建議與swiper共用一個索引值,最好將swiper與指示點的索引區分開,即用不同的變量,然后兩者同步變化就可以了!
下面直接來展示一個自定義指示面板,又可以解決抖動問題的案例!
1、邏輯梳理
1>先解決抖動問題,用@animationfinish改變當前滑塊的值;
<template> <view class="swipers-wrap"> <swiper @animationfinish="swiperChange" :current="currentSwiper" circular="true" class="swipers-view" :autoplay="autoplay" @change="dotChange"> <block v-for="(item,index) in swiperList" :key="index"> <swiper-item> <view class="swipers-best-hot-video"> 美景展示~ </view> <view class="swipers-image-view"> <image :src="item.imgUrl" mode="aspectFill" class="swipers-image"></image> <view class="swipers-title"> {{item.title}} </view> </view> </swiper-item> </block> </swiper> <!--重置指示面板(小圓點)的樣式 --> <view class="swipers-dots"> <block v-for="(item,index) in swiperList" :key="index"> <view class="dot" :class="{active: currentDot == index}"></view> </block> </view> </view> </template>
2>改變指示面板的索引,用@change;
<template> <view class="swipers-wrap"> <swiper @animationfinish="swiperChange" :current="currentSwiper" circular="true" class="swipers-view" :autoplay="autoplay" @change="dotChange"> <block v-for="(item,index) in swiperList" :key="index"> <swiper-item> <view class="swipers-best-hot-video"> 美景展示~ </view> <view class="swipers-image-view"> <image :src="item.imgUrl" mode="aspectFill" class="swipers-image"></image> <view class="swipers-title"> {{item.title}} </view> </view> </swiper-item> </block> </swiper> <!--重置指示面板(小圓點)的樣式 --> <view class="swipers-dots"> <block v-for="(item,index) in swiperList" :key="index"> <view class="dot" :class="{active: currentDot == index}"></view> </block> </view> </view> </template>
3>同步:對兩者賦值e.detail.current;
dotChange: function(e) {
this.currentDot = e.detail.current
},
swiperChange: function(e) {
this.currentSwiper = e.detail.current
},
2、完整代碼展示
<template> <view class="swipers-wrap"> <swiper @animationfinish="swiperChange" :current="currentSwiper" circular="true" class="swipers-view" :autoplay="autoplay" @change="dotChange"> <block v-for="(item,index) in swiperList" :key="index"> <swiper-item> <view class="swipers-best-hot-video"> 美景展示~ </view> <view class="swipers-image-view"> <image :src="item.imgUrl" mode="aspectFill" class="swipers-image"></image> <view class="swipers-title"> {{item.title}} </view> </view> </swiper-item> </block> </swiper> <!--重置指示面板(小圓點)的樣式 --> <view class="swipers-dots"> <block v-for="(item,index) in swiperList" :key="index"> <view class="dot" :class="{active: currentDot == index}"></view> </block> </view> </view> </template> <script> export default { data() { return { currentDot: 0, //指示面板對應的索引 currentSwiper: 0, //用來記錄當前swiper對應的索引 autoplay: true, swiperList:[ { 'imgUrl':'../../static/swiper.jpg', 'title':'白雲朵朵!' }, { 'imgUrl':'../../static/list.jpg', 'title':'藍天綠樹!' }, { 'imgUrl':'../../static/user.jpg', 'title':'boy!' } ] } }, methods: { dotChange: function(e) { this.currentDot = e.detail.current }, swiperChange: function(e) { this.currentSwiper = e.detail.current }, } } </script> <style> .swipers-wrap { height: auto; position: relative; background-color: blue; padding: 0 15upx; padding-bottom: 54upx; } .swipers-view { height: 420upx; } .swipers-best-hot-video { height: 90upx; line-height: 90upx; color: #f8f3bf; font-size: 36upx; text-align: center; } .swipers-image-view { height: 100%; position: relative; z-index: 1; } .swipers-image { width: 100%; height: 100%; } .swipers-image-view .swipers-title { position: absolute; z-index: 99; left: 25upx; bottom: 105upx; font-size: 24upx; font-weight: bold; color: #fff; font-size: 36upx; } /*用來包裹所有的小圓點 */ .swipers-dots { width: 100%; height: 50upx; display: flex; flex-direction: row; position: absolute; left: 0; bottom: 0upx; /* border:1upx solid red; */ display: flex; justify-content: center; align-items: center; /* border:1rpx solid green; */ } /*未選中時的小圓點樣式 */ .dot { width: 6px; height: 2upx; width: 55upx; background-color: #999; margin: 0 10upx; /* border:1upx solid red; */ } /*選中以后的小圓點樣式 */ .dot.active { height: 2upx; width: 80upx; background-color: #fff; margin: 0 10upx; } </style>