swiper輪播圖出現瘋狂抖動(小程序)


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>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM