count-down.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. // component/count-down/count-down.js
  2. Component({
  3. /**
  4. * 组件的属性列表
  5. */
  6. lifetimes: {
  7. attached: function () {
  8. // 在组件实例进入页面节点树时执行
  9. // 如果自动倒计时
  10. this.setItemStyle();
  11. this.properties.autoplay && this.properties.timestamp && this.start();
  12. },
  13. detached: function () {
  14. // 在组件实例被从页面节点树移除时执行
  15. clearInterval(this.properties.timer);
  16. this.properties.timer = null;
  17. },
  18. },
  19. // 以下是旧式的定义方式,可以保持对 <2.2.3 版本基础库的兼容
  20. attached: function () {
  21. // 在组件实例进入页面节点树时执行
  22. // 如果自动倒计时
  23. this.properties.autoplay && this.properties.timestamp && this.start();
  24. },
  25. detached: function () {
  26. // 在组件实例被从页面节点树移除时执行
  27. clearInterval(this.properties.timer);
  28. this.properties.timer = null;
  29. },
  30. //数据监听
  31. observers: {
  32. 'height,borderColor,bgColor,fontSize,color':function(){
  33. this.setItemStyle();
  34. }
  35. },
  36. properties: {
  37. timestamp: {
  38. type:Number,
  39. value:0,
  40. observer:function(newVal,oldVal,changePath){
  41. // 如果倒计时间发生变化,清除定时器,重新开始倒计时
  42. this.clearTimer();
  43. this.start();
  44. }
  45. },
  46. autoplay:{
  47. type:Boolean,
  48. value:true
  49. },
  50. // 用英文冒号(colon)或者中文(zh)当做分隔符,false的时候为中文,如:"11:22"或"11时22秒"
  51. separator: {
  52. type: String,
  53. value: 'colon'
  54. },
  55. // 分隔符的大小,单位rpx
  56. separatorSize: {
  57. type: [Number, String],
  58. value: 30
  59. },
  60. // 分隔符颜色
  61. separatorColor: {
  62. type: String,
  63. value: "#303133"
  64. },
  65. // 字体颜色
  66. color: {
  67. type: String,
  68. value: '#303133'
  69. },
  70. // 字体大小,单位rpx
  71. fontSize: {
  72. type: [Number, String],
  73. value: 30
  74. },
  75. // 背景颜色
  76. bgColor: {
  77. type: String,
  78. value: '#fff'
  79. },
  80. // 数字框高度,单位rpx
  81. height: {
  82. type: [Number, String],
  83. value: 'auto'
  84. },
  85. // 是否显示数字框
  86. showBorder: {
  87. type: Boolean,
  88. value: false
  89. },
  90. // 边框颜色
  91. borderColor: {
  92. type: String,
  93. value: '#303133'
  94. },
  95. showSeconds:{
  96. type:Boolean,
  97. value:true
  98. },
  99. showMinutes:{
  100. type:Boolean,
  101. value:true
  102. },
  103. showHours:{
  104. type:Boolean,
  105. value:true
  106. },
  107. showDays:{
  108. type:Boolean,
  109. value:true
  110. },
  111. hideZeroDay:{
  112. type:Boolean,
  113. value:false
  114. },
  115. },
  116. /**
  117. * 组件的初始数据
  118. */
  119. data: {
  120. d: '00', // 天的默认值
  121. h: '00', // 小时的默认值
  122. i: '00', // 分钟的默认值
  123. s: '00', // 秒的默认值
  124. timer: null, // 定时器
  125. seconds: 0, // 记录不停倒计过程中变化的秒数
  126. itemStyle:'',
  127. letterStyle:''
  128. },
  129. /**
  130. * 组件的方法列表
  131. */
  132. methods: {
  133. setItemStyle(){
  134. let style = '';
  135. if(this.height) {
  136. style += `height:${this.properties.height}rpx`;
  137. style += `width:${this.properties.height}rpx`;
  138. }
  139. if(this.properties.showBorder) {
  140. style += `border-style:solid;`
  141. style += `border-color:${this.properties.borderColor};`
  142. style += `border-width:1px;`
  143. }
  144. if(this.properties.bgColor) {
  145. style += `background-color:${this.properties.bgColor};`
  146. }
  147. let ls = '';
  148. if(this.properties.fontSize) ls += `font-size:${this.properties.fontSize}rpx;`
  149. if(this.properties.color) ls += `color:${this.properties.color};`
  150. this.setData({itemStyle:style,letterStyle:ls});
  151. },
  152. // 倒计时
  153. start() {
  154. // 避免可能出现的倒计时重叠情况
  155. this.clearTimer();
  156. if (this.properties.timestamp <= 0) return;
  157. this.properties.seconds = Number(this.properties.timestamp);
  158. this.formatTime(this.properties.seconds);
  159. this.properties.timer = setInterval(() => {
  160. this.properties.seconds--;
  161. // 发出change事件
  162. this.triggerEvent('change', {seconds:this.properties.seconds}, {})
  163. if (this.properties.seconds < 0) {
  164. return this.end();
  165. }
  166. this.formatTime(this.properties.seconds);
  167. }, 1000);
  168. },
  169. // 格式化时间
  170. formatTime(seconds) {
  171. // 小于等于0的话,结束倒计时
  172. seconds <= 0 && this.end();
  173. let [day, hour, minute, second] = [0, 0, 0, 0];
  174. day = Math.floor(seconds / (60 * 60 * 24));
  175. // 判断是否显示“天”参数,如果不显示,将天部分的值,加入到小时中
  176. // hour为给后面计算秒和分等用的(基于显示天的前提下计算)
  177. hour = Math.floor(seconds / (60 * 60)) - day * 24;
  178. // showHour为需要显示的小时
  179. let showHour = null;
  180. if (this.properties.showDays) {
  181. showHour = hour;
  182. } else {
  183. // 如果不显示天数,将“天”部分的时间折算到小时中去
  184. showHour = Math.floor(seconds / (60 * 60));
  185. }
  186. minute = Math.floor(seconds / 60) - hour * 60 - day * 24 * 60;
  187. second = Math.floor(seconds) - day * 24 * 60 * 60 - hour * 60 * 60 - minute * 60;
  188. // 如果小于10,在前面补上一个"0"
  189. showHour = showHour < 10 ? '0' + showHour : showHour;
  190. minute = minute < 10 ? '0' + minute : minute;
  191. second = second < 10 ? '0' + second : second;
  192. day = day < 10 ? '0' + day : day;
  193. this.setData({
  194. d:day,
  195. h:showHour,
  196. i:minute,
  197. s:second
  198. })
  199. },
  200. // 停止倒计时
  201. end() {
  202. this.clearTimer();
  203. this.triggerEvent('end', {}, {})
  204. },
  205. // 清除定时器
  206. clearTimer() {
  207. if (this.properties.timer) {
  208. // 清除定时器
  209. clearInterval(this.properties.timer);
  210. this.properties.timer = null;
  211. }
  212. }
  213. }
  214. })