0%

JavaScript / Vue.js 实现时分秒倒计时

我们平常浏览网页的时候,经常见到“距游戏公测1天2小时3分钟4秒”这样的倒计时器。时间如沙漏般一点点的减少,不仅能挑起用户的兴趣,而且让页面提升了一点逼格,还填补掉一些尴尬的空白位置。最近写得越来越多,有用没用都让加个倒计时,干脆记录下来,免得重复造轮子。

实现的方法并不复杂,关键是理解如何计算,尤其对我这种数学不好的人而言。下面两个 demo 将分别用纯 JavaScript 、基于 Vue.js 的 JavaScript 实现。注,代码中可能包含部分 ES6 语法,但相信很容易理解。

JavaScript

创建一个 countdown 方法,用于计算并在控制台打印距目标时间的日、时、分、秒数,每隔一秒递归执行一次。

msec 是当前时间距目标时间的毫秒数,由时间戳相减得到,我们将以这个数为基础计算。我们都知道1天等于24小时,1小时等于60分钟,1分钟等于60秒,1秒等于1000毫秒。所以,msec / 1000 / 60 / 60 / 24 保留整数就是天数。如果换用 % 取余数,再保留整数后得到的就是小时数。以此类推就能算出其他所有数。

1
function countdown () {
2
  // 目标日期时间戳
3
  const end = Date.parse(new Date('2017-12-01'))
4
  // 当前时间戳
5
  const now = Date.parse(new Date())
6
  // 相差的毫秒数
7
  const msec = end - now
8
  // 计算时分秒数
9
  let day = parseInt(msec / 1000 / 60 / 60 / 24)
10
  let hr = parseInt(msec / 1000 / 60 / 60 % 24)
11
  let min = parseInt(msec / 1000 / 60 % 60)
12
  let sec = parseInt(msec / 1000 % 60)
13
  // 个位数前补零
14
  hr = hr > 9 ? hr : '0' + hr
15
  min = min > 9 ? min : '0' + min
16
  sec = sec > 9 ? sec : '0' + sec
17
  // 控制台打印
18
  console.log(`${day}${hr}小时 ${min}分钟 ${sec}秒`)
19
  // 一秒后递归
20
  setTimeout(function () {
21
    countdown()
22
  }, 1000)
23
}

控制台打印结果:

1
27天 07小时 49分钟 10秒
2
27天 07小时 49分钟 09秒
3
27天 07小时 49分钟 08秒
4
...

Vue.js

如果单纯使用 JavaScript ,我们需要在每次计算后手动更新 DOM 元素(将数据显示给用户),既不方便又难以维护。实际项目中更多的是配合前端框架,将计算结果实时渲染到页面上。

页面结构中的数据来自 Vue 实例的 data 对象。

1
<div id="app">{{ `${day}天 ${hr}小时 ${min}分钟 ${sec}分钟` }}</div>

mounted 是 Vue 的生命周期方法,可以理解为在页面加载完毕后执行 countdown 方法。countdown 方法每隔一秒会执行一次,并将计算结果分别赋予变量 dayhrminsec,同时改变的还有页面上显示的内容。

1
new Vue({
2
  el: '#app',
3
  data: function () {
4
    return {
5
      day: 0, hr: 0, min: 0, sec: 0
6
    }
7
  },
8
  mounted: function () {
9
    this.countdown()
10
  },
11
  methods: {
12
    countdown: function () {
13
      const end = Date.parse(new Date('2017-12-01'))
14
      const now = Date.parse(new Date())
15
      const msec = end - now
16
      let day = parseInt(msec / 1000 / 60 / 60 / 24)
17
      let hr = parseInt(msec / 1000 / 60 / 60 % 24)
18
      let min = parseInt(msec / 1000 / 60 % 60)
19
      let sec = parseInt(msec / 1000 % 60)
20
      this.day = day
21
      this.hr = hr > 9 ? hr : '0' + hr
22
      this.min = min > 9 ? min : '0' + min
23
      this.sec = sec > 9 ? sec : '0' + sec
24
      const that = this
25
      setTimeout(function () {
26
        that.countdown()
27
      }, 1000)
28
    }
29
  }
30
})

相关环境:Windows 7 x64 / Vue.js 2.4.4