1. 名称:
    CountDown
  2. 作者:
    站长老左
  3. 来源:
  4. 浏览:
    13625
  5. 最新更新:
    2016-11-14
  6. 收藏2


先来看下最终效果:

输入图片说明

git源:http://git.oschina.net/dotton/CountDown

分步骤-性子急的朋友,可以直接看最后那段代码。

wxml文件放个text

<text>second: {{second}} micro second:{{micro_second}}</text>


在js文件中调用

function countdown(that) {
  var second = that.data.second
  if (second == 0) {
    // console.log("Time Out...");
    that.setData({
      second: "Time Out..."
    });
    return ;
  }
  var time = setTimeout(function(){
    that.setData({
      second: second - 1
    });
    countdown(that);
  }
  ,1000)
}

Page({
    data: {
        second: 3
    },
    onLoad: function() {
        countdown(this);
    }
});

运行验证下,从10走到1s,然后显示时间到。

于是继续将毫秒完善,注意毫秒的步长受限于系统的时间频率,于是我们精确到0.01s即10ms

js

/* 秒级倒计时 */
function countdown(that) {
  var second = that.data.second
  if (second == 0) {
    that.setData({
      second: "Time out!",
      micro_second: "micro_second too."
    });
    clearTimeout(micro_timer);
    return ;
  }
  var timer = setTimeout(function(){
    that.setData({
      second: second - 1
    });
    countdown(that);
  }
  ,1000)
}

/* 毫秒级倒计时 */
// 初始毫秒数,同时用作归零
var micro_second_init = 100;
// 当前毫秒数
var micro_second_current = micro_second_init;
// 毫秒计时器
var micro_timer;

function countdown4micro(that) {
  if (micro_second_current <= 0) {
    micro_second_current = micro_second_init;
  }
  micro_timer = setTimeout(function(){
    that.setData({
      micro_second: micro_second_current - 1
    });
    micro_second_current--;
    countdown4micro(that);
  }
  ,10)
}

Page({
    data: {
        second: 2,
        micro_second: micro_second_init
    },
    onLoad: function() {
        countdown(this);
        countdown4micro(this);
    }
});

wxml文件

<text style="display: block;">second: {{second}}s</text>

<text>{{micro_second}}</text>

如此,当秒级运行完毕时,毫秒级timer即clearTimeout,并将字本显示为'micro_second too'

再添加一个countdown4micro方法,使得显示剩余 0:3:19 89这样形式的倒数

function dateformat(second) {
    var dateStr = "";
    var hr = Math.floor(second / 3600);
    var min = Math.floor((second - hr * 3600) / 60);
    var sec = (second - hr * 3600 - min * 60);// equal to => var sec = second % 60;
    dateStr = hr + ":" + min + ":" + sec;
    return dateStr;
}

目前有2个时钟,影响性能,合并下去掉countdown,于是countdown4micro变成以下的样子:

function countdown4micro(that) {

    var loop_second = Math.floor(loop_index / 100);
    // 得知经历了1s
    if (cost_micro_second != loop_second) {
        // 赋予新值
        cost_micro_second = loop_second;
        // 总秒数减1
        total_second--;

    }
      // 每隔一秒,显示值减1; 渲染倒计时时钟
    that.setData({
      clock:dateformat(total_second - 1)
    });

      if (total_second == 0) {
        that.setData({
          // micro_second: "",
          clock:"时间到"
        });
        clearTimeout(micro_timer);
        return ;
      }    

  if (micro_second_current <= 0) {
    micro_second_current = micro_second_init;
  }
  micro_timer = setTimeout(function(){
    that.setData({
      micro_second: micro_second_current - 1
    });
    micro_second_current--;
    // 放在最后++,不然时钟停止时还有10毫秒剩余
    loop_index ++;
    countdown4micro(that);
  }
  ,10)
}

如此这般,毫秒与时分秒是分别运行渲染的,再次改造,程序可读性更好。dateformat针对于毫秒操作,而不接受秒为数。同时还省却了计算100次为1s的运算

/** 
 * 需要一个目标日期,初始化时,先得出到当前时间还有剩余多少秒
 * 1.将秒数换成格式化输出为XX天XX小时XX分钟XX秒 XX
 * 2.提供一个时钟,每10ms运行一次,渲染时钟,再总ms数自减10
 * 3.剩余的秒次为零时,return,给出tips提示说,已经截止
 */

// 定义一个总毫秒数,以一分钟为例。TODO,传入一个时间点,转换成总毫秒数
var total_micro_second = 2 * 1000;

/* 毫秒级倒计时 */
function countdown(that) {
      // 渲染倒计时时钟
      that.setData({
          clock:dateformat(total_micro_second)
      });

      if (total_micro_second <= 0) {
          that.setData({
              clock:"已经截止"
          });
          // timeout则跳出递归
          return ;
      }    
      setTimeout(function(){
        // 放在最后--
        total_micro_second -= 10;
        countdown(that);
    }
    ,10)
}

// 时间格式化输出,如3:25:19 86。每10ms都会调用一次
function dateformat(micro_second) {
      // 秒数
      var second = Math.floor(micro_second / 1000);
      // 小时位
      var hr = Math.floor(second / 3600);
      // 分钟位
      var min = Math.floor((second - hr * 3600) / 60);
      // 秒位
    var sec = (second - hr * 3600 - min * 60);// equal to => var sec = second % 60;
    // 毫秒位,保留2位
    var micro_sec = Math.floor((micro_second % 1000) / 10);
    return hr + ":" + min + ":" + sec + " " + micro_sec;
}

Page({
    data: {
        clock: ''
    },
    onLoad: function() {
        countdown(this);
    }
});

经过如上优化,代码量减少一半,运行效率也高了。


共0 条评论
  1. 加载评论

评论内容:

发表评论
  1. 全部组件分类
  2. 瀑布流
  3. 示例
  4. 提示组件(ToolTip)
  5. 下拉刷新、上拉加载
  6. Toast
  7. 选项卡(tab)
  8. 图表
  9. 卡片切换
  10. 菜单
  11. 筛选
  12. 星级评分
  13. 选择器
  14. 滑动删除
  15. 手势密码
  16. Switch
  17. 搜索
  18. 游戏
  19. 弹幕
  20. 懒加载
  21. 布局
  22. 应用模仿
  23. Emoji
  24. 转盘抽奖
  25. 插件
  26. UI库
  27. 动画
  28. 下拉列表
  29. SnackBar
  30. HTML解析
  31. 日历
  32. 点餐小程序
  33. 购物效果
  34. 框架
  35. 渲染引擎
  36. 商城
  37. 吸顶停留
  38. 会议
  39. 分享
  40. 其他
最新评论