微信小程序 倒计时组件实现代码


Posted in Javascript onOctober 24, 2016

功能: 适用于电商应用的限时团购、商品秒杀等

先来看下最终效果:

微信小程序 倒计时组件实现代码

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);
  }
});

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

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

Javascript 相关文章推荐
javascript学习笔记(十九) 节点的操作实现代码
Jun 20 Javascript
Javascript全局变量var与不var的区别深入解析
Dec 09 Javascript
javascript内置对象arguments详解
Mar 16 Javascript
轻松实现js图片预览功能
Jan 18 Javascript
基于jQuery实现发送短信验证码后的倒计时功能(无视页面关闭)
Sep 02 Javascript
jquery层级选择器(匹配父元素下的子元素实现代码)
Sep 05 Javascript
jQuery动态改变多行文本框高度的方法
Sep 07 Javascript
JS实现禁止用户使用Ctrl+鼠标滚轮缩放网页的方法
Apr 28 Javascript
浅谈react+es6+webpack的基础配置
Aug 09 Javascript
javascript回调函数详解
Feb 06 Javascript
C#程序员入门学习微信小程序的笔记
Mar 05 Javascript
判断js数据类型的函数实例详解
May 23 Javascript
微信小程序 WXDropDownMenu组件详解及实例代码
Oct 24 #Javascript
微信小程序 购物车简单实例
Oct 24 #Javascript
Select2.js下拉框使用小结
Oct 24 #Javascript
微信小程序 绘图之饼图实现
Oct 24 #Javascript
用jmSlip编写移动端顶部日历选择控件
Oct 24 #Javascript
微信小程序 富文本转文本实例详解
Oct 24 #Javascript
微信小程序 参数传递详解
Oct 24 #Javascript
You might like
全国FM电台频率大全 - 17 湖北省
2020/03/11 无线电
JavaScript中的对象化编程
2008/01/16 Javascript
自己做的模拟模态对话框实现代码
2012/05/23 Javascript
Javascript call和apply区别及使用方法
2013/11/14 Javascript
javascript禁用Tab键脚本实例
2013/11/22 Javascript
JS实现控制表格行内容垂直对齐的方法
2015/03/30 Javascript
总结javascript中的六种迭代器
2016/08/16 Javascript
Angular 理解module和injector,即依赖注入
2016/09/07 Javascript
浅谈Angular.js中使用$watch监听模型变化
2017/01/10 Javascript
JS简单实现获取元素的封装操作示例
2017/04/07 Javascript
前端防止用户重复提交js实现代码示例
2018/09/07 Javascript
简单的React SSR服务器渲染实现
2018/12/11 Javascript
jQuery访问json文件中数据的方法示例
2019/01/28 jQuery
vue中filters 传入两个参数 / 使用两个filters的实现方法
2019/07/15 Javascript
百度小程序自定义通用toast组件
2019/07/17 Javascript
JavaScript实现京东放大镜效果
2019/12/03 Javascript
vscode 配置vue+vetur+eslint+prettier自动格式化功能
2020/03/23 Javascript
ES6 async、await的基本使用方法示例
2020/06/06 Javascript
antd vue table跨行合并单元格,并且自定义内容实例
2020/10/28 Javascript
结合Python的SimpleHTTPServer源码来解析socket通信
2016/06/27 Python
Python线程下使用锁的技巧分享
2018/09/13 Python
Python实现个人微信号自动监控告警的示例
2019/07/03 Python
解决Python二维数组赋值问题
2019/11/28 Python
Python之Matplotlib文字与注释的使用方法
2020/06/18 Python
基于Python+QT的gui程序开发实现
2020/07/03 Python
详解Python中list[::-1]的几种用法
2020/11/16 Python
MIXIT官网:俄罗斯最大的化妆品公司之一
2020/01/25 全球购物
Python里面search()和match()的区别
2016/09/21 面试题
期末自我鉴定
2014/02/02 职场文书
小学生中国梦演讲稿
2014/04/23 职场文书
学雷锋树新风演讲稿
2014/05/10 职场文书
晚自修旷课检讨书怎么写
2014/11/17 职场文书
python 自动刷新网页的两种方法
2021/04/20 Python
快速学习Oracle触发器和游标
2021/06/30 Oracle
mysql字段为NULL索引是否会失效实例详解
2022/05/30 MySQL