微信小程序setTimeout实现单个倒计时以及循环倒计时(超详细,项目需要做个笔录)

先来看一下效果图吧

循环倒计时

单个倒计时

接下来看一下具体代码吧

循环倒计时

wxml

<!--pages/commodity/commodity-time-limit/index.wxml-->
<wxs module="format" src="../../../../wxs/format.wxs"></wxs>
<wxs module="filter" src="../../../../wxs/filter.wxs"></wxs>
<!-- 顶部 S -->
<view class="head-top">
	<image class="back" src="https://ico.dongtiyan.com/tu-105.png"></image>
	<view class="navbar custom-class"
		style='height:{{navHeight}}px;background: url("https://ico.dongtiyan.com/tu-163.png"); background-size: 100% 100%;position: fixed;top:0'>
		<view class="navbar-action-wrap navbar-action-group row item-center" style='top:{{navTop + 7}}px;' bindtap="goBack">
			<image src="https://ico.dongtiyan.com/tu-109.png"></image>
			<view class="navbar-title" style="top:{{navTop}}">秒杀专区</view>
		</view>
	</view>
	<!-- 头部 S -->
	<view class="time-limit-top">
		<view class="top-title {{Index==index? 'active': ''}}" wx:for="{{topList}}" wx:key="index" data-index="{{index}}"
			bindtap="chooseCut">
			<view>{{item.title}}</view>
			<view class="desc {{Index==index? 'actives': ''}}">{{item.desc}}</view>
		</view>
	</view>
	<!-- 头部 E -->
</view>
<!-- 轮播 S -->
<view class="banner">
	<!-- 轮播图 S -->
	<swiper class="viewpager" autoplay="{{autoplay}}" interval="{{interval}}" duration="{{duration}}"
		circular="{{circular}}" bindchange="changeSwiper">
		<swiper-item wx:for="{{slideshow}}" wx:key="index">
			<navigator url="../../../{{item.url}}" hover-class="none" style="display: inline;">
				<image src="{{item.image}}" class="image"></image>
			</navigator>
		</swiper-item>
	</swiper>
	<view class="dots">
		<block wx:for="{{slideshow}}" wx:key="index">
			<view class="dot {{index == currentSwiper ? 'active-z' : ''}}"></view>
		</block>
	</view>
	<!-- 轮播图 E -->
</view>
<!-- 写入内容 S -->
<block wx:if="{{goodsList.length != 0}}">
	<view class="list1">
		<!-- 轮播 E -->
		<!-- 写入内容 S -->
		<view class="seckill-top">
			<view class="seckill-top-left">
				<image src="https://ico.dongtiyan.com/tu-107.png"></image>
				<view class="seckill-top-size">限时抢购</view>
				<image src="https://ico.dongtiyan.com/tu-106.png"></image>
				<view class="seckill-top-size">正品保障</view>
			</view>
			<!-- <view class="seckill-top-right">
				<view class="distance-time">距结束还剩{{remainTime}}</view>
				<view class="count-down-time">
					<view class="time">{{hour}}</view>
					<view class="space-mark">:</view>
					<view class="time">{{minute}}</view>
					<view class="space-mark">:</view>
					<view class="time">{{second}}</view>
				</view>
			</view> -->
		</view>
		<!-- list -->
		<view class="seckill-module">
			<view class="seckill-goods">
				<view class="seckill-goods-item" wx:for="{{goodsList}}" wx:key="index" bindtap="chooseSeckillDetail"
					data-goodsid="{{item.goods_id}}" data-shopid="{{item.shop_id}}" data-index="{{index}}">
					<block wx:if="{{newTime > item.seckill_end_time}}">
						<view class="has-gone">已结束</view>
					</block>
					<block wx:else>
						<block wx:if="{{item.store_count == 0}}">
							<view class="has-gone">已抢光</view>
						</block>
					</block>
					<view class="seckill-goods-image">
						<image src="{{item.goods_pic_url}}"></image>
					</view>
					<view class="seckill-goods-info">
						<view class="seckill-goods-name">{{item.goods_name}}</view>
						<view class="seckill-goods-desc">
							<view class="seckill-goods-desc-title">
								<block wx:if="{{item.is_selected == 1}}">
									<text>精选</text>
								</block>
								<block wx:if="{{item.is_postage == 0}}">
									<text>包邮</text>
								</block>
								<block wx:if="{{item.is_new == 1}}">
									<text>新品</text>
								</block>
							</view>
							<view class="seckill-goods-count-down-layout">
								<view class="seckill-goods-count-down">
									<text class="seckill-goods-count-down-left" wx:if="{{Index == 0}}">截止时间:</text>
									<text class="seckill-goods-count-down-left" wx:if="{{Index == 1}}">即将开始:</text>
									<text>
										<text>{{item.endTime.day}}</text>
										<text>天 </text>
										<text>{{item.endTime.hou}}</text>
										<text> : </text>
										<text>{{item.endTime.min}}</text>
										<text> : </text>
										<text>{{item.endTime.sec}}</text>
									</text>
								</view>
							</view>
						</view>
						<view class="seckill-goods-btn">
							<view class="seckill-goods-btn-left">
								<text>¥ </text>
								<text>{{item.shop_price}}</text>
							</view>
							<view class="seckill-goods-btn-right" wx:if="{{newTime < item.seckill_end_time}}">购买</view>
							<view class="seckill-goods-btn-rights" wx:else>已结束</view>
						</view>
					</view>
				</view>
			</view>
		</view>
		<!-- 写入内容 E -->
	</view>
	<!-- 写入内容 E -->

	<view class="loading" hidden="{{!loadMore}}">加载中...</view>
	<view class="loading" hidden="{{!loadAll}}">已经加载完了~</view>
</block>
<block wx:else>
	<view class="kong">
		抱歉! 商品跑丢了~
	</view>
</block>

wxss

/* pages/commodity/commodity-time-limit/index.wxss */
/* 顶部 S */
.head-top {
  width: 100%;
  height: 351rpx;
}
.head-top .back {
  width: 100%;
  height: 351rpx;
  z-index: -1;
}
.navbar {
  width: 100%;
  overflow: hidden;
  position: absolute;
  top: 0;
  left: 0;
  z-index: 10;
  flex-shrink: 0;
}

.navbar-title {
  width: 100%;
  box-sizing: border-box;
  padding-left: 40px;
  padding-right: 105px;
  line-height: 35px;
  text-align: center;
  margin: 0 auto;
  /* position: absolute; */
  position: fixed;
  left: 0;
  z-index: 10;
  color: #fff;
  font-size: 13px;
  font-weight: Medium;
  font-family: "PingFang-SC-Medium";
  text-overflow: ellipsis;
  overflow: hidden;
  white-space: nowrap;
  display: flex;
}

.navbar-action-wrap {
  display: -webkit-flex;
  display: flex;
  -webkit-box-align: center;
  -ms-flex-align: center;
  -webkit-align-items: center;
  align-items: center;
  /* position: absolute; */
  left: 10px;
  z-index: 11;
  line-height: 1;
  position: fixed;
}
.navbar-action-wrap image {
  width: 12px;
  height: 18px;
}
.navbar-action-group {
  border-radius: 20px;
  overflow: hidden;
}

.navbar-action_item {
  padding: 3px 0;
  color: #333;
}

.navbar-action-group .navbar-action_item {
  border-right: 1px solid #f0f0f0;
  padding: 3px 14px;
}

.navbar-action-group .last {
  border-right: none;
}

.navbar-title-size {
  font-size: 10px;
  margin-right: 20rpx;
  align-self: center;
  margin: 0 auto;
}

.navbar-title-size.active {
  color: red;
  border-bottom: 2px solid red;
}

.scroll-box {
  position: absolute;
  height: 100%;
}
/* 顶部 E */
.time-limit-top {
  height: 100rpx;
  display: flex;
  align-self: center;
  justify-content: space-between;
  margin-top: -208rpx;
  margin-left: 94rpx;
  margin-right: 94rpx;
}
.time-limit-top .top-title {
  width: 178rpx;
  height: 90rpx;
  align-self: center;
  text-align: center;
  color: #fff;
  font-size: 32rpx;
  border-radius: 10rpx;
}
.time-limit-top .top-title .desc {
  font-size: 24rpx;
  margin-top: 13rpx;
  color: #FACACA;
}
.active {
  background: #FFFFFF;
  color: #FE5669 !important;
}
.actives {
  color: #FE7D8B;
}

/* 正在秒杀 下期预告 */


/* 轮播图 */

.banner {
  height: 240rpx;
  margin-left: 20rpx;
  margin-right: 20rpx;
  text-align: center;
  margin-top: -60rpx;
}

.viewpager {
  width: 100%;
  height: 240rpx;
  border-radius: 0.5rem;
  margin-bottom: 22rpx;
  overflow: hidden;
}

.viewpager .image {
  width: 100%;
  height: 100%;
  border-radius: 0.5rem;
}

/*用来包裹所有的小圆点 */
.dots {
  height: 36rpx;
  display: flex;
  flex-direction: row;
  justify-content: center;
  margin-top: -50rpx;
  z-index: 99;
  position: relative;
}

/*未选中时的小圆点样式 */

.dot {
  width: 7rpx;
  height: 6rpx;
  border-radius: 3rpx;
  margin-right: 26rpx;
  background-color: #FFFFFF;
}

/*选中以后的小圆点样式 */

.active-z {
  width: 26rpx;
  height: 6rpx;
  border-radius: 3rpx;
  background-color: #E5627B;
}
/* 写入内容 */
.seckill-top {
  background: #fff;
  height: 88rpx;
  margin: 14rpx 20rpx 0;
  border-top-left-radius: 20rpx;
  border-top-right-radius: 20rpx;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 20rpx;
}
.seckill-top-left {
  font-size: 24rpx;
  color: #000000;
  display: flex;
  align-self: center;
}
.seckill-top-left image:nth-child(1){
  width: 25rpx;
  height: 27rpx;
  margin-right: 9rpx;
  padding-top: 4rpx;
}
.seckill-top-left .seckill-top-size {
  margin-right: 39rpx;
}
.seckill-top-left image:nth-child(3) {
  width: 22rpx;
  height: 26rpx;
  margin-right: 8rpx;
  padding-top: 4rpx;
}
.seckill-top-right {
  font-size: 24rpx;
  color: #666666;
  display: flex;
  align-items: center;
}
.seckill-top-right .distance-time {
  margin-right: 14rpx;
}
.count-down-time {
  display: flex;
  align-items: center;
  font-size: 24rpx;
  
}
.seckill-top-right .count-down-time .time {
  width: 34rpx;
  text-align: center;
  color: #FFFFFF;
  background: #000000;
}
.seckill-top-right .count-down-time .space-mark {
  margin: 0 10rpx;
}

/* 秒杀抢购 */
.seckill-module {
  background-color: #FFFFFF;
  margin: 0 20rpx 20rpx;
  border-bottom-left-radius: 20rpx;
  border-bottom-right-radius: 20rpx;
  padding-top: 20rpx;
}


.seckill-goods-item {
  margin: 0 0 40rpx;
  padding-bottom: 20rpx;
  display: flex;
}

.seckill-goods-item:last-child {
  margin: 10rpx 0 20rpx;
}

.seckill-goods-image {
  width: 238rpx;
  height: 238rpx;
  border-radius: 20rpx;
  overflow: hidden;
  margin: 0 20rpx;
}

.has-gone {
  width: 120rpx;
  height: 120rpx;
  border-radius: 50%;
  background-color: #000000;
  opacity: 0.5;
  font-size: 30rpx;
  color: #FFFFFF;
  text-align: center;
  line-height: 120rpx;
  position: absolute;
  left: 100rpx;
  margin-top: 70rpx;
}

.seckill-goods-image image {
  width: 100%;
  height: 100%;
}

.seckill-goods-info {
  padding: 0 16rpx;
}

.seckill-goods-name {
  font-size: 28rpx;
  color: #333333;
  font-weight: bold;
  text-overflow: -o-ellipsis-lastline;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  width: 400rpx;
}

.seckill-goods-desc {
  margin: 10rpx 0 20rpx;
}

.seckill-goods-desc-title {
  font-size: 20rpx;
  color: #F28D37;
  padding: 5rpx 10rpx;
  border-radius: 10rpx;
}

.seckill-goods-desc-title text {
  background-color: #FFF3E8;
  margin-right: 10rpx;
  padding: 2rpx 10rpx;
  border-radius: 5rpx;
}

.seckill-goods-count-down-layout {
  text-align: right;
}

.seckill-goods-count-down {
  width: 100%;
  font-size: 24rpx;
  color: #F0133C;
  margin-top: 20rpx;
}

.seckill-goods-count-down text:nth-child(1) {
  margin-right: 10rpx;
}

.seckill-goods-count-down text:nth-child(2) text:nth-child(1),
.seckill-goods-count-down text:nth-child(2) text:nth-child(3),
.seckill-goods-count-down text:nth-child(2) text:nth-child(5) {
  border-radius: 6rpx;
}

.seckill-goods-btn {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.seckill-goods-btn-left {
  color: #F72149;
  font-size: 40rpx;
  font-weight: bold;
}

.seckill-goods-btn-left text:nth-child(1) {
  font-size: 24rpx;
}

.seckill-goods-btn-right {
  font-size: 30rpx;
  color: #FFFFFF;
  background-color: #F72149;
  width: 115rpx;
  text-align: center;
  height: 42rpx;
  line-height: 42rpx;
  border-radius: 10rpx;
}
.seckill-goods-btn-rights {
  font-size: 30rpx;
  color: #999999;
  background-color: #f6f6f6;
  width: 115rpx;
  text-align: center;
  height: 42rpx;
  line-height: 42rpx;
  border-radius: 10rpx;
}

.kong {
  text-align: center;
  color: #999999;
  font-size: 24rpx;
  margin-top: 300rpx;
}

js

Page({
    data: {
        goodsList: [
            {
                seckill_end_time: 1606751700
                seckill_strat_time: 1604224200
            }
        ],
        datetimeDown: "",                  // 开始倒计时时间
        // 秒杀倒计时
        hour: "",       // 时
        minute: "",        // 分
        second: "",         // 秒
        loadMore: false,                // 上拉加载的变量, 默认false  隐藏
        loadAll: false,                 // 没有数据的变量, 默认false ,  隐藏
        newTime: 0,                       // 当前时间戳
    },
    /**
   * 秒杀倒计时
   */
  timeFormat(param) {//小于10的格式化函数
    return param < 10 ? '0' + param : param;
  },
  countDown: function () {
    // 获取当前时间, 同样得到活动结束时间数组
    let newTime = Date.parse(new Date()) / 1000;         // 当前时间
    let seckill = this.data.goodsList;
    seckill.forEach(i => {
      let endTime = ''
      if (this.data.Index == 0) {            // Index判断当前是秒杀还是预告商品, 根据项目需求
        endTime = i.seckill_end_time;
      } else if (this.data.Index == 1) {
        endTime = i.seckill_strat_time;
      }
      let obj = null;
      let time = (endTime - newTime);
      // 如果活动未结束,对时间进行处理
      if (time > 0) {
        // 获取天、时、分、秒
        let day = parseInt(time / (60 * 60 * 24));
        let hou = parseInt(time % (60 * 60 * 24) / 3600);
        let min = parseInt(time % (60 * 60 * 24) % 3600 / 60);
        let sec = parseInt(time % (60 * 60 * 24) % 3600 % 60);
        obj = {
          day: this.timeFormat(day),
          hou: this.timeFormat(hou),
          min: this.timeFormat(min),
          sec: this.timeFormat(sec)
        }
      } else {//活动已结束,全部设置为'00'
        obj = {
          day: '00',
          hou: '00',
          min: '00',
          sec: '00'
        }
        clearTimeout(this.countDown)
      }
      i.endTime = obj;
    })
    // 渲染,然后每隔一秒执行一次倒计时函数
    this.setData({ goodsList: seckill, newTime: newTime })        // newTime当前时间戳,是为了判断当前商品是否结束或开始根据需求修改就好
    setTimeout(this.countDown, 1000);
  },
})

主要是js,有什么不懂的可以下方留言,或者有更好的解决方案

单个倒计时

wxml

<view class="count-down-show">
					<view class="time">{{txtTime.day}}</view>
					<view class="space-mark">天</view>
					<view class="time">{{txtTime.hou}}</view>
					<view class="space-mark">:</view>
					<view class="time">{{txtTime.min}}</view>
					<view class="space-mark">:</view>
					<view class="time">{{txtTime.sec}}</view>
				</view>

js

Page({
    data: {
        datetimeDown:'2020/11/30, 23:55:00',            // 结束时间
        detetimeStrat: '2020/11/29, 23:55:00',          // 开始时间
    },
    
    /**
   * 倒计时
   */
  timeFormat(param) {//小于10的格式化函数
    return param < 10 ? '0' + param : param;
  },
  countDown: function () {
    var _this = this;
    var time = 0;
    var obj = {};
    let endTime = 0;
    if(_this.data.statusindex != 1) {
      endTime = new Date(_this.data.datetimeDown.replace(/-/g, '/')).getTime();             // 结束时间戳
    } else {
      endTime = new Date(_this.data.detetimeStrat.replace(/-/g, '/')).getTime();             // 开始时间戳
    }
    
    let timestamp = new Date().getTime();                     // 当前时间戳
    time = (endTime - timestamp) / 1000;                // 时间差
    if(time > 0) {
      var day = parseInt(time / (60 * 60 * 24));
      var hou = parseInt(time % (60 * 60 * 24) / 3600);
      var min = parseInt(time % (60 * 60 * 24) % 3600 / 60);
      var sec = parseInt(time % (60 * 60 * 24) % 3600 % 60);
      obj = {
        day: _this.timeFormat(day),
        hou: _this.timeFormat(hou),
        min: _this.timeFormat(min),
        sec: _this.timeFormat(sec)
      }
    } else {        // 活动结束
      obj = {
        day: "00",
        hou: "00",
        min: "00",
        sec: "00"
      }
      if(_this.data.statusindex == 1) {
        _this.setData({
          statusindex: 0
        })
        _this.data.timeIntervalSingle
      } else {
        _this.setData({
          statusIndex: 1
        })
        clearTimeout(_this.data.timeIntervalSingle); //清除定时器
      }
    }
    var timeIntervalSingle = setTimeout(_this.countDown, 1000);
    _this.setData({
      timeIntervalSingle,
      txtTime: obj,
      timestamp: timestamp
    })
  },
})

以上就是所有代码有什么不懂的可以下方留言

如果对你有用,关注一下博主的小程序,登录一下给予支持,以后有什么开源好用的源码都会上传到小程序

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值