倒计时读秒不受页面刷新、关闭、跳转影响

4,733 阅读2分钟

实现功能:

前端在做登录或者注册模块的时候可能会涉及到验证手机号,点击获取验证码按钮后按钮处于禁用状态,同时显示倒计时秒数,当秒数读完的时候恢复按钮原本状态,同时在页面刷新后或者关闭或跳转都不会影响读秒。

分析:

我们要实现的有:

1、点击按钮后进行读秒并让按钮处于禁用状态;

2、读秒不受页面变化的影响;

3、读秒结束后按钮恢复原本状态

思路:

1、要不受页面影响,那就需要用到时间戳去做时间差的判断(利用未来的某一时间与当前时间进行相减)

2、当离开当前页面后还要进行读秒,所以要在离开或刷新或关闭页面时将你设定的那个未来的某一时间戳存储起来(这里我用的本地存储),在下次回到这个页面的时候通过读取上次存在本地存储时间戳的数据与当前的时间戳进行相减,如果<=0,则恢复按钮的状态,否则将继续进行读秒

代码(在vue-cli脚手架中书写):

结构部分:

<input type="text" />
    <button @click="getCode()" :disabled="btnFlag">
      {{ result > 0 && result ? result : "获取验证码" }}
    </button>

data部分:

data() {
    return {
      btnFlag: false,
      timer: null,
      result: null,   //此变量为截止时间戳与当前时间戳相减的差
      timeStamp: null,//此变量为倒计时截止的时间戳
    };
  },

首先进入获取验证码这个页面时先去判断本地存储里存储的时间戳与当前的时间戳相减的差是否<=0;

created() {
    window.addEventListener('beforeunload',()=>{
      if (this.timeStamp) {
      localStorage.setItem("reduceTimeStamp", JSON.stringify(this.timeStamp));
        clearInterval(this.timer);
    }
    })
    let temp = JSON.parse(localStorage.getItem("reduceTimeStamp"));
    let NowStamp = new Date().getTime();
    //如果<=0说明倒计时已结束,将按钮恢复原始状态
    if (+temp - NowStamp <= 0) {
      this.result = null;
      this.btnFlag = false;
    } else {
      this.result = parseInt((temp - NowStamp) / 1000);
      console.log(this.result);
    }
  },

 mounted() {
    if (this.result) this.getCode();
  }

主要函数部分:

countTime() {
     //如果result<=0,证明上一次读秒已结束,需要重新设置新的时间戳
      if (!this.result) {
        let currentStamp = new Date().getTime();
        this.timeStamp = new Date().getTime() + 30 * 1000; //我设置了30秒this.result = (this.timeStamp - currentStamp) / 1000;
      }
      this.timer = setInterval(() => {
        this.result--;
        if (this.result === 0) {
          clearInterval(this.timer);
          this.timer = null;
          this.btnFlag = false;
        }
      }, 1000);
    },
//点击获取验证码按钮
getCode() {
      this.btnFlag = !this.btnFlag;
      this.countTime();
    }

其实刚开始做的时候我是将时间戳的存储那部分的代码放到destroyed钩子函数里边的,但是页面直接刷新或者直接关闭都不会触发destroyed钩子函数,所以这里要借助源生的beforeunload事件帮助我们完成,详情可以去查阅MDN文档。

总结

这个需求的核心在于去使用时间戳和监听页面的改变,以及使用定时器;如有错误,欢迎各位大佬的给出优化建议!