视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
js实现多个倒计时并行 js拼团倒计时
2020-11-27 22:00:38 责编:小采
文档

本文是对类似于拼团,多个商品每个都有各自的倒计时,一开始接到接到这个需求也是头疼了一阵子,如果是在商品列表少的时候完全就可以写成死的,固定的变量,写几个定时器就ok了,

但是这次数据是活的,看一些拼团app都可以实现,既然能实现就搞起来,有了以下的想法 使用环境 vue

写一个准备渲染的死数据

data () {
 return {
 list: [ // 准备渲染的数据
 {
 remainTime: 900000, // 距离结束还有多久
 remainTimeStr: '' // 展示文案
 },
 {
 remainTime: 400000,
 remainTimeStr: ''
 },
 {
 remainTime: 60500,
 remainTimeStr: ''
 },
 ]
 }
}

百度copy一个倒计时的方法

countdowm (timestamp) {
 let self = this
 let timer = setInterval(function () {
 let nowTime = new Date()
 let endTime = new Date(timestamp)
 let t = endTime.getTime() - nowTime.getTime()
 if (t > 0) {
 let day = Math.floor(t / 800000)
 let hour = Math.floor((t / 3600000) % 24)
 let min = Math.floor((t / 60000) % 60)
 let sec = Math.floor((t / 1000) % 60)
 hour = hour < 10 ? '0' + hour : hour
 min = min < 10 ? '0' + min : min
 sec = sec < 10 ? '0' + sec : sec
 let format = ''
 if (day > 0) {
 format = `${day}天${hour}小时${min}分${sec}秒`
 }
 if (day <= 0 && hour > 0) {
 format = `${hour}小时${min}分${sec}秒`
 }
 if (day <= 0 && hour <= 0) {
 format = `${min}分${sec}秒`
 }
 self.content = format
 } else {
 clearInterval(timer)
 self.content = 'over'
 }
 }, 1000)
}

捋清逻辑

首先, 根据逻辑对倒计时的方法进行更改,我们直接使用的就是距离结束还有多少时间的时间戳 ,我的思路是用一个定时器达到一个并行多个倒计时的思路,所以先将方法进行优化

  • 不需要获取时间
  • 也不需要一些时间计算
  • 因为是多个倒计时并行 所以清楚定时器的逻辑需要进行更改
  • countdowm (timestamp) {
     let self = this
     let timer = setInterval(function () {
     let t = timestamp
     if (t > 0) {
     let day = Math.floor(t / 800000)
     let hour = Math.floor((t / 3600000) % 24)
     let min = Math.floor((t / 60000) % 60)
     let sec = Math.floor((t / 1000) % 60)
     day = day < 10 ? '0' + day : day
     hour = hour < 10 ? '0' + hour : hour
     min = min < 10 ? '0' + min : min
     sec = sec < 10 ? '0' + sec : sec
     let format = ''
     format = `${day}天${hour}小时${min}分${sec}秒`
     self.content = format
     } else {
     // clearInterval(timer)
     self.content = 'over'
     }
     }, 1000)
    }
    

    简化完毕, 把自己刚才的思路带进方法内

    在定时器里 写一个循环 每次减少一秒 让当前数据内remainTime时间戳-1000

    countdown () {
     let self = this
     let timer = setInterval(function () {
     for (let i = 0; i < self.list.length; i++) {
     self.list[i].remainTime -= 1000
     let t = self.list[i].remainTime
     if (t > 0) {
     let day = Math.floor(t / 800000)
     let hour = Math.floor((t / 3600000) % 24)
     let min = Math.floor((t / 60000) % 60)
     let sec = Math.floor((t / 1000) % 60)
     day = day < 10 ? '0' + day : day
     hour = hour < 10 ? '0' + hour : hour
     min = min < 10 ? '0' + min : min
     sec = sec < 10 ? '0' + sec : sec
     let format = ''
     format = `距离结束:<b>${day}</b> 天 <b>${hour}</b> 
    时 <b>${min}</b> 分 <b>${sec}</b> 秒`
     self.list[i].remainTimeStr = format
     } else {
     // 进行判断 如果数据内所有的倒计时已经结束,那么结束定时器, 如果没有那么继续执行定时器
     let flag = self.list.every((val, ind) => 
     
    val.remainTime <= 0)
     if (flag) clearInterval(timer)
     self.list[i].remainTimeStr = `距离结束:<b>00</b> 天 
    <b>00</b> 时 <b>00</b> 分 <b>00</b> 秒` // 结束文案
     }
     }
     }, 1000)
    }
    

    这样 并行多个定时器就做好了, 但是发现了一个问题 当你切换路由的时候 发下你的定时器如果未结束 他还在执行,这样对性能造成了一些影响, 虽说用户看不到,但是也要解决,提高用户浏览体验
    在你切换页面的时候 使用vue中的生命周期函数把数据更改为0 就ok

    destroyed () {
     this.list.forEach((val) => {
     val.remainTime = 0
     })
    }
    
    

    下载本文
    显示全文
    专题