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>