zoukankan      html  css  js  c++  java
  • 如何写一个简单又通用的倒计时函数?

    关于倒计时,可能大家都遇到/写过这样的UI: 13:15:16。

    嗯,一个最简单的倒计时,就是这样。

    你会怎么实现这个逻辑?

    下面是我的经历。

    第一次遇到这样的需求时,自然而然的一路平推,非常容易的就完成了。

    第二次遇到类似的需求,产品对我说要改成这样婶儿的:1天 13:15:16。没毛病,抡起键盘,一顿control c + control v。哎呀,需求有了一点变化,还得重新加点内容。

    第三次,产品说要这样:15:16。

    ......

    于是我们看到,前端的需求呈碎片化且变更频繁,即便使用 react、vue 等框架帮助我们解耦 UI 层和数据层(这极大的提高了开发效率),但面对需求我们依然疲于奔命。

    怎么解决?我认为最好的方法就是分离可变部分不变部分

    如何识别需求中的可变和不变部分,这需要我们开发者结合实际需求、过往经验、google等进行辨别。所以,没有最好的方法,只有现阶段你自己觉得好的方法。

    针对上面需求,哪些是可变的?哪些是不变的呢?

    变化部分

    1、表现形式,从 13:15:16 变成 1天 13:15:16 再变成 15:16
    2、倒计时结束,可能会有相应的操作,比如刷新页面
    3、等

    不变部分

    计算:输入时间值,返回符合要求的倒计时字符串。可以通过函数表示 string = format(fmt, timeValue)。

    // formatTime.js

    const RE_FORMAT = new RegExp('%([1-9]?)(.)', 'g')
    const ONE_SECOND = 1000;
    const ONE_MINUTE = ONE_SECOND * 60;
    const ONE_HOUR = ONE_MINUTE * 60;
    const ONE_DAY = ONE_HOUR * 24;
    /**
     * @param {RegExp} fmt 按照strftime的规则,但是多了个数字,比如 "%d"=>"02", "%1d" => "2",目前支持最多以天为单位的倒计时 
     * @param {time} diffTime 倒计时剩余时间 单位:毫秒
     * 
     * @return {String} fmt fmt格式的字符串
     */
    function format(fmt, diffTime) {
      if (diffTime === void 0 || diffTime < 0) return diffTime
      
      let day = parseInt(diffTime / ONE_DAY)
      diffTime -= day * ONE_DAY
      let h = parseInt(diffTime / ONE_HOUR)
      diffTime -= h * ONE_HOUR
      let m = parseInt(diffTime / ONE_MINUTE)
      diffTime -= m * ONE_MINUTE
      let s = parseInt(diffTime / ONE_SECOND)
    
      let res = fmt.replace(RE_FORMAT, function(_, digit, val) {
        switch (val) {
          case 'd': // 日,01-31
            return zpad(digit || 2, day);
          case 'H': // 时,01-24
            return zpad(digit || 2, h);
          case 'M': // 分,01-59
            return zpad(digit || 2, m);
          case 'S': // 秒,01-59
            return zpad(digit || 2, s);
          case '%':
            return '%';
          default: // 未匹配到,保持原样
            return _;
        }
      })
    
      return res
    }
    
    const ZEROS = '000000000';
    function zpad(n, v) {
      return (ZEROS + v).substr(-n)
    }
    
    export default {
      format,
      zpad
    }
    
    

    最后,在 Vue 中完成倒计时:

    import formatTime from './formatTime'
    
    data() {
      return {
        dataTime: '00:00:00'
      }
    },
    
    methods: {
      countDown(diffTime) {
        if (isNaN(diffTime) || diffTime === void 0) return
    
        if (diffTime < 0) return // to do something
        
        this.downTime = formatTime.format('%H:%M:%S', diffTime)
        
        clearTimeout(this.__timer)
        this.__timer = setTimeout(() => this.countDown(diffTime - 1000), 1000)
      },
    }
    

    当然,你不一定非得使用 vue。

    以上

  • 相关阅读:
    sql server delete语句
    sql server 通配符
    sql server join联结
    windows下如何使用两个版本的nodejs
    PHP的Trait 特性
    PHP错误与异常处理try和catch
    laravel belongsTo()&hasOne()用法详解
    Laravel Model 的 fillable (白名单)与 guarded (黑名单)
    js原生,缓动动画封装
    js原生轮播图
  • 原文地址:https://www.cnblogs.com/fayin/p/10009079.html
Copyright © 2011-2022 走看看