【微信小程序】实现垂直滚动消息、滚动广告,无限轮播

效果图

  1. 当消息是小于等于3行时,不轮播滚动,直接显示3条
    在这里插入图片描述

  2. 当消息大于3行时,轮播滚动(gif显示的问题,看起来不太流畅 )
    在这里插入图片描述

  3. 一列显示,大于3行,滚动显示
    在这里插入图片描述

  4. 一列显示,小于等于3行,静止效果

在这里插入图片描述
5. 可以通过代码动态修改颜色

let serviceData = {}
    serviceData.titlecolor = "#ffffff" //表头文字的颜色
    serviceData.titleBackground = "#FF7F00" //表头的背景
    let serviceArray = []
    let innerData1 = new Object()
    innerData1.color = "#999999" //表格文字颜色
    innerData1.title = "标题一"

在这里插入图片描述

实现原理

通过setInterval周期性执行的原理,周期性更新move,利用style="top:-{{move}}px"使view向上移动,当向上移动的距离是条目item的高度height的时候,表明一条item已经移除视野,这时候就应该在尾部添加一条数据,来实现
尾部添加数据的时间节点也是周期性的,再次利用setInterval来实现

      interval1 = setInterval(function () {
        that.setData({
          move: that.data.move + 1,
        })
      }, 18)
      interval2 = setInterval(function () {
        let detail = []
        for (let i = 1; i < that.data.lineArray.length; i++) {
          detail.push(that.data.lineArray[i])
        }
        detail.push(that.data.lineArray[0])
        that.setData({
          lineArray: detail,
          move: 0,
        })

      }, 684)
      //684/18 = 38(一行的高度)

两个interval的时间是什么关系呢,先确定interval1 的时间点是18(数值不同,滚动的速度不同),然后用18*item的高度,就是interval2的时间。

实现代码

wxml

<view class="notice-container" style="height:{{totalHeight}}px" catchtap="onNewProduct">
  <view class="notice-title-container">
    <block wx:for="{{titleArray}}" wx:key="index" data-index="{{index}}">
      <view class="notice-line-title-item" style="background:{{item.background}};color:{{item.color}}">
        {{item.value}}</view>
    </block>
  </view>
  <view class="notice-swiper" style="height:{{lineArray.length*38}}px">
    <view class="notice-position" style="top:-{{move}}px">
      <view class="notice-for" wx:for="{{lineArray}}" wx:key="index" data-index="{{index}}">
        <view class="notice-item-root-container">
          <view class="notice-item-container">
            <block wx:for="{{item}}" wx:key="index" data-index="{{index}}" wx:for-item="innerItem">
              <view class="notice-line-item-container" style="color:{{innerItem.color}}">
                <view class="notice-line-item">{{innerItem.value}}</view>
              </view>
            </block>
          </view>
          <view class="notice-item-divider"></view>
        </view>
      </view>
    </view>
  </view>
</view>

wxss

.notice-container {
  /* display: flex;
  flex-direction: column; */
  width: 702rpx;
  margin-left: 24rpx;
  background: #FFFFFF;
  border-radius: 16rpx;
  overflow: hidden;
}

.notice-title-container {
  width: 100%;
  height: 30px;
  display: flex;
  flex-direction: row;
}

.notice-line-title-item {
  font-size: 28rpx;
  font-family: PingFang SC;
  font-weight: 500;
  height: 60rpx;
  line-height: 60rpx;
  color: #FFFFFF;
  height: 100%;

  display: -webkit-box;
  overflow: hidden;
  text-overflow: ellipsis;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  display: flex;
  flex-direction: row;
  justify-content: center;
  flex: 1;
}
.notice-swiper {
  width: 100%;
  height: fit-content;
  float: left;
  overflow: hidden;
  position: relative;
}

.notice-position {
  width: 100%;
  float: left;
  position: absolute;
}

.notice-for {
  width: 100%;
  float: left;
  height: 38px;
}


.notice-item-root-container {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 38px;
}

.notice-item-container {
  width: 100%;
  height: 37px;
  display: flex;
  flex-direction: row;
}

.notice-item-divider {
  width: 640rpx;
  height: 1px;
  background: #f4f4f4;
  margin-left: 31rpx;
}
.notice-line-item-container {
  height: 100%;
  flex: 1;
  display: flex;
  flex-direction: row;
  overflow: hidden;
  max-lines: 1;
  white-space: nowrap;
  justify-content: center;
}
.notice-line-item{
  margin-left: 6rpx;
  margin-right: 6rpx;
  font-size: 24rpx;
  font-family: PingFang SC;
  font-weight: 500;
  color: #333333;
  width: fit-content;
  display: flex;
  flex-direction: row;
  align-items: center;
  height: 100%;
  overflow: hidden;
  line-height: 24rpx;
  max-lines: 1;
  white-space: nowrap;
}

js

// example/notice/index.js
let interval1
let interval2
Page({

  /**
   * 页面的初始数据
   */
  data: {
    serviceData: null,
    titleArray: [],
    move: 0,
    searchBottom: 0,
    tabHeight: 0,
    totalHeight: 0
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    let serviceData = {}
    serviceData.titlecolor = "#ffffff"
    serviceData.titleBackground = "#999999"
    let serviceArray = []
    let innerData1 = new Object()
    innerData1.color = "#999999"
    innerData1.title = "标题一"
    //3列6行
    // innerData1.value = ["列1、行1dfaddddddfadfad", "列1、行2", "列1、行3", "列1、行4", "列1、行5", "列1、行6"]
    //3列4行
    innerData1.value = ["列1行1dfaddddddfadfad", "列1、行2", "列1、行3", "列1、行4"]
    //3列3行
    // innerData1.value = ["列1行1dfaddddddfadfad", "列1、行2", "列1、行3"]
    let innerData2 = new Object()
    innerData2.color = "#333333"
    innerData2.title = "标题二"
    //3列6行
    // innerData2.value = ["列2、行1", "列2、行2", "列2、行3", "列2、行4", "列2、行5", "列2、行6"]
    //3列4行
    // innerData2.value = ["列2、行111111111111111111111", "列2、行2", "列2、行3", "列2、行4"]
    //3列3行
    innerData2.value = ["列2、行111111111111111111111", "列2、行2", "列2、行3"]
    let innerData3 = new Object()
    innerData3.color = "#d61515"
    innerData3.title = "标题三"
    //3列6行
    // innerData3.value = ["列3、行1", "列3、行2", "列3、行3", "列3、行4", "列3、行5", "列3、行6"]
    //3列4行
    // innerData3.value = ["列3、行1", "列3、行2", "列3、行3", "列3、行4"]
    //3列3行
    innerData3.value = ["列3、行1", "列3、行2","列3、行3"]
    serviceArray.push(innerData1)
    serviceArray.push(innerData2)
    serviceArray.push(innerData3)
    serviceData.array = serviceArray
    console.log(serviceData)
    //以上模拟服务端数据
    let lineArray = []
    let titleArray = []

    let count = serviceData.array[0].value.length
    let array = serviceData.array
    let itemColorArray = []
    array.forEach(e => {
      let itemData = {}
      itemData.value = e.title
      itemData.color = serviceData.titlecolor
      itemData.background = serviceData.titleBackground
      titleArray.push(itemData)
      itemColorArray.push(e.color)
    })
    let colmnIndex = 0
    for (let i = 0; i < count; i++) {
      let itemArray = []
      array.forEach(e => {
        let itemData = {}
        itemData.value = e.value[i]
        itemData.color = itemColorArray[colmnIndex]
        itemArray.push(itemData)
        colmnIndex++
      })
      colmnIndex = 0
      lineArray.push(itemArray)
    }
    this.setData({
      lineArray,
      titleArray,
    })
    if (lineArray.length > 3) {
      //当行数大于5的时候滚动轮播
      this.setData({
        totalHeight: 3 * 38
      })
      let that = this
      interval1 = setInterval(function () {
        that.setData({
          move: that.data.move + 1,
        })
      }, 18)
      interval2 = setInterval(function () {
        let detail = []
        for (let i = 1; i < that.data.lineArray.length; i++) {
          detail.push(that.data.lineArray[i])
        }
        detail.push(that.data.lineArray[0])
        that.setData({
          lineArray: detail,
          move: 0,
        })

      }, 684)
      //684/18 = 38(一行的高度)
    } else {
      this.setData({
        totalHeight: lineArray.length * 38+38
      })
    }

  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {
	
  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {
    clearInterval(interval1)
    clearInterval(interval2)
  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  }
})

需要注意的是:如果该页面使用在tabbar页面的时候,切换tab的时候需要在onHide停止轮询,在onshow中重新加载数据继续轮询,否则一直轮询是会耗电发烫的

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值