商品定时器

262 阅读2分钟
  • 产品需求:定时器
    • 当前周期之前为"已结束"
    • 在当天00:00:00 - 10:00:00倒计时
    • 到当天时间 10:00:00 为"抢购中", 抢光了:用户点击按钮,明天的开始计时,今天的为"已抢光"
    • 周期之后为"未开始"
  • 环境: vuejs
  • js代码基本实现:
  • 工具函数
  /* 
      * 左补
  */
  function leftpad(str, len, ch) {
    str = String(str);
    var i = -1;
    if (!ch && ch !== 0) ch = ' ';
    len = len - str.length;
    while (++i < len) {
      str = ch + str;
    }
    return str;
  }
  // 参数:结束时间 开始时间(服务器存取)
  function countDown (endTime, standardTime) {
    // 时间戳 
    var distance = endTime - standardTime
    var day = Math.floor(distance / (1000 * 60 * 60 * 24));
    var hours = Math.floor(distance / (1000 * 60 * 60) % 24);
    var minutes = Math.floor(distance / (1000 * 60) % 60);
    var seconds = Math.floor(distance / 1000 % 60);
    return {
      day: leftpad(day, 2, 0),
      hours: leftpad(hours, 2, 0),
      minutes: leftpad(minutes, 2, 0),
      seconds: leftpad(seconds, 2, 0)
    }
  }
  • // 倒计时的回调函数
    getCountTime() {
      let nowDate = new Date().getTime() ;
      // 后台取服务器时间
      let serviceTimeStamp = new Date(this.timer.serviceTime).getTime()
      // 设备时间
      let deviceTimeStamp = new Date(this.timer.deviceTime).getTime()
      let endTimeStamp = new Date(this.timer.endTime).getTime()
      // 根据服务器时间计算当前设备的时间误差
      let distanceTime = Math.abs(deviceTimeStamp - serviceTimeStamp);
      let standardTime
      // 误差调整
      if (deviceTimeStamp > serviceTimeStamp) {
        standardTime = nowDate - distanceTime
      } else {
        standardTime = nowDate + distanceTime
      }
      let timer = setTimeout(() => {
      // 获取倒计时时间
        let countDownTime = countDown(endTimeStamp, standardTime)
        // 到终点清空计时器并停止在00:00:00
        if (Number(countDownTime.hours) <= 0 && Number(countDownTime.minutes) <= 0 && Number(countDownTime.seconds) <= 0) {
          clearTimeout(timer)
          countDownTime = {
            hours: '00',
            minutes: '00',
            seconds: '00'
          }
          // 改变状态 -- 抢购中
          this.timer.beginNow = true
        } else {
          this.getCountTime();
        }
        // 在网页上刷新
        this.refreshTime(countDownTime);
      }, 900); // 不能取1000,会被延时 !
    },
  • 响应式数据的页面刷新
    refreshTime (timer) {
      this.date.forEach((item, index) => {
      // 倒计时的星期几 才会得到更新
        if (index+1 === this.timer.countDay) {
          item.hours = timer.hours
          item.minutes = timer.minutes
          item.seconds = timer.seconds
        }
        this.$set(this.date, index, item)
      })
    },
    // 结束时间:1.当天页面进入的时候开始, 2.抢购光,第二天开始计时
    endTime(addDay){
      let serviceNow = new Date(new Date(this.timer.serviceTime).getTime())
      let dates = serviceNow.getDate() + addDay
      this.timer.countDay = serviceNow.getDay()
      // 只能+1 倒计时的时间
      this.timer.countDay += addDay
      this.timer.endTime = serviceNow.getFullYear() + '-' + (serviceNow.getMonth()+1) + "-" + dates + ' ' + "10:00:00"
      this.getCountTime()
    }
  • 页面初始化数据,vue的钩子函数mounted
        this.timer.serviceTime = this.timer.serviceTime || new Date().getTime()
        // 不足
        let serviceNow = new Date(new Date(this.timer.serviceTime).getTime())
        this.weekday = serviceNow.getDay()
    
        console.log(this.weekday)
        // 当前设备的时间
        this.timer.deviceTime= new Date()
        // 到当前的下一天23:59:59
        if (this.weekday > 0 && this.weekday < 6) {
            this.endTime(0)
          // 当前的时间大于了结束时间
          if (serviceNow.getTime() > new Date(this.timer.endTime).getTime() && serviceNow.getMonth() === serviceNow.getMonth() && serviceNow.getDate() === serviceNow.getDate()) {
            this.timer.beginNow = true
          }
        }
    ```