赞
踩
在工作中开发一个页面,多少都会用到轮播图,但是由于微信官方提供的轮播图swiper组件局限性太大了,所以接下来我会教大家怎么去自定义轮播图的进度条。
如果你的项目只是简单的修改小圆点的颜色,那么只需要修改官方提供的indicator-color
和indicator-active-color
参数就可以了
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
indicator-color | color | rgba(0, 0, 0, .3) | 指示点颜色(也就是没选中小圆点时的颜色) |
indicator-active-color | color | #000000 | 当前选中的指示点颜色 |
wxml:
<swiper indicator-dots="true" circular="true" indicator-color="white" indicator-active-color="orange">
<swiper-item>
<view class="red"></view>
</swiper-item>
<swiper-item>
<view class="green"></view>
</swiper-item>
<swiper-item>
<view class="blue"></view>
</swiper-item>
</swiper>
wxss:
swiper { height: 400rpx; } swiper-item view { height: 100%; } .red { background-color: Pink; } .green { background-color: PaleGreen; } .blue { background-color: SkyBlue; }
另外如果需要更改位置的话加上这两行样式就好了
.wx-swiper-dots {
position: relative;
/* unset复原重置属性值 */
left: unset !important;
right: 0rpx;
}
.wx-swiper-dots .wx-swiper-dots-horizontal {
margin-bottom: 0rpx;
}
好了,接下里就是进入正题了,手动写一个静态的进度条我相信各位小伙伴都会,那么要怎么做才能让它随之我们的轮播图切换而变化呢?这里就需要用到current
这个轮播图当前页的下标
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
current | number | 0 | 当前所在滑块的 index |
wxml:在结构上,我先手写一个进度条,然后让其悬浮在轮播图上面,接着再用三元运算符来判断轮播图的下标于进度条的下标是否相等,相等就把选中的样式赋给标签就好了,另外还需要绑定一个bindchange方法
来监听current
下标的改变。
<view class="parent"> <!-- 轮播图 --> <swiper bindchange="monitorCurrent" indicator-dots="{{false}}" circular="true" indicator-color="white" indicator-active-color="orange" current="{{current}}" autoplay="{{autoplay}}"> <block wx:for="{{backgroundArr}}" wx:key="*this"> <swiper-item> <view class="{{item}}"></view> </swiper-item> </block> </swiper> <!-- 自定义轮播图进度点 --> <view class="dots"> <block wx:for="{{backgroundArr}}" wx:for-index="index" wx:key="*this"> <view class="{{current==index?'active':''}}"></view> </block> </view> </view>
js:在动作上,我们只需要监听轮播图的下标变化就好了,一有变动更新下标即可。另外你会发现我动态控制了轮播图是否动播放,这是为了解决小程序长时间后台返回后页面轮播图出现反复抖动的bug。
Page({ /** * 页面的初始数据 */ data: { //轮播图的数组 backgroundArr: ['red', 'green', 'blue'], //轮播图当前的下标 current: 0, //是否自动播放轮播图 autoplay: false, }, //监听轮播图的下标 monitorCurrent: function (e) { // console.log(e.detail.current) let current = e.detail.current; this.setData({ current: current }) }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { }, /** * 生命周期函数--监听页面显示 */ onShow: function () { //开启轮播图 this.setData({ autoplay: true }) }, /** * 生命周期函数--监听页面隐藏 */ onHide: function () { //关闭轮播图 this.setData({ autoplay: false }) }, /** * 生命周期函数--监听页面卸载 */ onUnload: function () { //关闭轮播图 this.setData({ autoplay: false }) }, })
wxss:
.parent { position: relative; } swiper { height: 400rpx; } swiper-item view { height: 100%; } .red { background-color: Pink; } .green { background-color: PaleGreen; } .blue { background-color: SkyBlue; } .dots { position: absolute; bottom: 30rpx; display: flex; justify-content: center; align-items: center; width: 100%; } .dots view { width: 10rpx; height: 10rpx; margin: 0 6rpx; border-radius: 10rpx; background-color: #fff; } .dots .active { width: 30rpx; background-color: orange; }
如果要显示页码的话,我们只需要使用轮播图的下标(从0开始)加上1来表示当前页,轮播图数组的长度来表示页码总数就好了。另外轮播图自动播放也要控制下,不然后台返回后会有bug。
wxml:
<view class="parent">
<!-- 轮播图 -->
<swiper bindchange="monitorCurrent" indicator-dots="{{false}}" circular="true" indicator-color="white"
indicator-active-color="orange" current="{{current}}" autoplay="{{autoplay}}">
<block wx:for="{{backgroundArr}}" wx:key="*this">
<swiper-item>
<view class="{{item}}"></view>
</swiper-item>
</block>
</swiper>
<!-- 自定义轮播图进度点 -->
<view class="dots">{{current+1}}/{{backgroundArr.length}}</view>
</view>
js:
Page({ /** * 页面的初始数据 */ data: { //轮播图的数组 backgroundArr: ['red', 'green', 'blue'], //轮播图当前的下标 current: 0, //是否自动播放轮播图 autoplay: false, }, //监听轮播图的下标 monitorCurrent: function (e) { // console.log(e.detail.current) let current = e.detail.current; this.setData({ current: current }) }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { }, /** * 生命周期函数--监听页面显示 */ onShow: function () { //开启轮播图 this.setData({ autoplay: true }) }, /** * 生命周期函数--监听页面隐藏 */ onHide: function () { //关闭轮播图 this.setData({ autoplay: false }) }, /** * 生命周期函数--监听页面卸载 */ onUnload: function () { //关闭轮播图 this.setData({ autoplay: false }) }, })
wxss:
.parent { position: relative; } swiper { height: 400rpx; } swiper-item view { height: 100%; } .red { background-color: Pink; } .green { background-color: PaleGreen; } .blue { background-color: SkyBlue; } .dots { position: absolute; right: 20rpx; bottom: 20rpx; width: 70rpx; height: 35rpx; line-height: 35rpx; text-align: center; font-size: 24rpx; border-radius: 20rpx; background-color: rgba(0, 0, 0, 0.4); color: #fff; }
接着就是这种有计时器的进度条了,这种写起来会麻烦一点。
wxml:在结构上,在写进度条时需要有两层,以我的GIF为例,外层用来放灰色的背景,内层用来放橙色的背景,接着我们只需要动态的去绑定width参数就好了。
<view class="parent"> <!-- 轮播图 --> <swiper bindchange="monitorCurrent" indicator-dots="{{false}}" circular="true" indicator-color="white" indicator-active-color="orange" current="{{current}}" autoplay="{{autoplay}}" interval="{{interval}}"> <block wx:for="{{backgroundArr}}" wx:key="*this"> <swiper-item> <view class="{{item}}"></view> </swiper-item> </block> </swiper> <!-- 自定义轮播图进度点 --> <view class="dots-parent"> <block wx:for="{{backgroundArr}}" wx:for-index="index" wx:key="*this"> <view class="progress-line-bg"> <view class="{{current==index?'progress-line':''}}" style="width:{{progressNum}}%"></view> </view> </block> </view> </view>
js:在动作上,我们需要先封装一个轮播图进度条计时器的方法,其功能是使用选中的进度条从0达到100的填充效果,接着在生命周期onShow
函数上初次执行这个方法,紧接着轮播图翻页时,再二次去执行这个方法就好了。需要注意的是计时器是在全局data对象里面注册的,这样做的用意是每次执行时都可以确保把上一个计时器给清理掉。另外考虑到性能的问题,在页面隐藏(onHide
)或者卸载(onUnload
)时,我们要把轮播图给关了,防止再次生成计时器,接着还需把没执行完的计时器也清理掉,具体看代码解析。另外我设置轮播图自动翻页的时间是5秒,需要修改的话记得把计时器那也从新计算一下。
Page({ /** * 页面的初始数据 */ data: { //轮播图的数组 backgroundArr: ['red', 'green', 'blue'], //轮播图当前的下标 current: 0, //是否自动播放轮播图 autoplay: false, // 轮播图自动切换时间间隔 interval: 5000, //轮播图进度条的计时器 progressNumInterval: null, //轮播图进度条的进度 progressNum: 0 }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) {}, /** * 生命周期函数--监听页面显示 */ onShow: function () { //开启自动轮播 this.setData({ autoplay: true }) // 初次执行顶部轮播图的进度条的进度点 this.progressLineInterval(); }, //监听轮播图的下标 monitorCurrent: function (e) { // console.log(e.detail.current) let current = e.detail.current; this.setData({ current: current }) // 二次执行顶部轮播图的小圆点的进度点 this.progressLineInterval(); }, //封装轮播图进度条计时器的方法 progressLineInterval: function () { // 清理小圆点的计时器 clearInterval(this.data.progressNumInterval) // 清理小圆点的进度 this.setData({ progressNum: 0, }) /** * 轮播图的切换时间为5秒,进度条的进度为1-100%, * 因为5000/100=50毫秒,所以每50毫秒就要执行1个进度点 * 另外需要把计时器寄存在data{}对象上,否则会清理不掉上一个计时器 * */ this.data.progressNumInterval = setInterval(() => { let progressNum = this.data.progressNum; // console.log(progressNum) if (progressNum < 100) { progressNum++; } else { progressNum = 0; // 清理进度条的计时器 clearInterval(this.data.progressNumInterval) } this.setData({ progressNum: progressNum }) }, 50) }, // 暂停轮播图 pauseSwiper() { // 关闭自动轮播 this.setData({ autoplay: false }) // 清理进度条的计时器 clearInterval(this.data.progressNumInterval) }, /** * 生命周期函数--监听页面隐藏 */ onHide: function () { this.pauseSwiper() }, /** * 生命周期函数--监听页面卸载 */ onUnload: function () { this.pauseSwiper() }, })
wxss:
.parent { position: relative; } swiper { height: 400rpx; } swiper-item view { height: 100%; } .red { background-color: Pink; } .green { background-color: PaleGreen; } .blue { background-color: SkyBlue; } .dots-parent { position: absolute; bottom: 30rpx; display: flex; justify-content: center; align-items: center; width: 100%; } .dots-parent .progress-line-bg { margin-left: 10rpx; width: 45rpx; height: 8rpx; border-radius: 8rpx; background-color: rgba(255, 255, 255, 0.5); } .progress-line { height: 8rpx; border-radius: 8rpx; background-color: #E42C2C; }
另外,如果你要在实体机上查看效果,点击预览就好了,如果点的是真机测试,会有延迟,导致进度条不能填充到100%的bug
觉得不错的小伙伴记得点个赞哦!!(づ ̄3 ̄)づ╭❤~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。