countdown.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. // eslint-disable-next-line no-undef
  2. export default Behavior({
  3. behaviors: [],
  4. properties: {
  5. time: {
  6. type: Date,
  7. value: new Date().getTime() + 86400000,
  8. observer: function (newVal, oldVal) {
  9. if (newVal && !oldVal) {
  10. this.getLatestTime();
  11. }
  12. }
  13. },
  14. status: {
  15. type: Boolean,
  16. value: true,
  17. observer: function (newVal) {
  18. if (newVal) {
  19. this.init();
  20. } else if (!newVal) {
  21. clearInterval(this.data.timer);
  22. }
  23. }
  24. },
  25. timeType: {
  26. type: String,
  27. value: 'datetime'
  28. },
  29. format: {
  30. type: String,
  31. value: '{%d}天{%h}时{%m}分{%s}秒'
  32. },
  33. isZeroPadd: {
  34. type: Boolean,
  35. value: true,
  36. },
  37. countdownType: {
  38. type: String,
  39. value: 'normal'
  40. },
  41. isClearInterval: {
  42. type: Boolean,
  43. value: true
  44. }
  45. },
  46. data: {
  47. initAddTime: 0,
  48. timer: null,
  49. date: [],
  50. },
  51. ready: function () {
  52. this.getLatestTime();
  53. },
  54. detached: function () {
  55. if (this.data.isClearInterval) {
  56. clearInterval(this.data.timer);
  57. }
  58. },
  59. pageLifetimes: {
  60. hide() {
  61. if (this.data.isClearInterval) {
  62. clearInterval(this.data.timer);
  63. }
  64. },
  65. show() {
  66. if (this.data.isClearInterval) {
  67. this.getLatestTime();
  68. }
  69. }
  70. },
  71. methods: {
  72. // 自动补零
  73. zeroPadding(num) {
  74. num = num.toString();
  75. return num[1] ? num : '0' + num;
  76. },
  77. init() {
  78. clearInterval(this.data.timer);
  79. const timer = setTimeout(() => {
  80. this.getLatestTime.call(this);
  81. }, 1000);
  82. this.setData({
  83. timer
  84. });
  85. },
  86. getLatestTime() {
  87. let {
  88. time,
  89. status,
  90. timeType,
  91. initAddTime,
  92. countdownType,
  93. } = this.data;
  94. // IOS不支持2019-04-23 的日期格式
  95. let countDownTime = time;
  96. if (countdownType === 'normal') { //当countdownType === normal时,不影响之前的代码
  97. if (timeType !== 'second') {
  98. countDownTime = typeof time === 'string' ? countDownTime.replace(/-/g, '/') : countDownTime;
  99. countDownTime = Math.ceil((new Date(countDownTime).getTime() - new Date().getTime()) / 1000);
  100. }
  101. if (countDownTime < 0 && timeType !== 'second') {
  102. this._getTimeValue(0);
  103. this.CountdownEnd();
  104. return;
  105. }
  106. if (countDownTime - initAddTime > 0) {
  107. this.getLatestForCountDown(countDownTime);
  108. } else if (countDownTime - initAddTime < 0) {
  109. this.getLatestForAddTime(countDownTime);
  110. } else if (countDownTime - initAddTime === 0) {
  111. if (initAddTime <= 0) {
  112. this._getTimeValue(countDownTime);
  113. }
  114. this.CountdownEnd();
  115. }
  116. if (status && countDownTime - initAddTime !== 0) {
  117. this.init.call(this);
  118. }
  119. } else if (countdownType === 'anniversary') { // 当countdownType === anniversary时,为纪念日模式
  120. if (timeType === 'second') { // 纪念日模式不能设置timeType === second
  121. console.error(`countdownType为${countdownType}类型时,不可设置timeType值为second`);
  122. } else {
  123. countDownTime = typeof time === 'string' ? countDownTime.replace(/-/g, '/') : countDownTime;
  124. countDownTime = Math.ceil((new Date().getTime() - new Date(countDownTime).getTime()) / 1000);
  125. if (countDownTime >= 0) { // countDownTime计算结果不能为负数
  126. this.getLatestForCountDown(countDownTime);
  127. this.init.call(this);
  128. } else {
  129. console.error('time传值错误');
  130. }
  131. }
  132. } else { // countdownType 不能设置为 normal,anniversary 以外的值
  133. console.error('错误的countdownType类型');
  134. }
  135. },
  136. getLatestForAddTime(countDownTime) {
  137. let {
  138. initAddTime
  139. } = this.data;
  140. if (initAddTime !== Math.abs(countDownTime)) {
  141. initAddTime++;
  142. this._getTimeValue(initAddTime);
  143. this.setData({
  144. initAddTime
  145. });
  146. }
  147. },
  148. getLatestForCountDown(countDownTime) {
  149. this._getTimeValue(countDownTime);
  150. this.setData({
  151. time: this.data.timeType === 'second' ? --countDownTime : this.data.time,
  152. });
  153. },
  154. _getTimeValue(countDownTime) {
  155. const {
  156. format
  157. } = this.data;
  158. const date = [];
  159. const fomatArray = format.split(/(\{.*?\})/);
  160. const formatType = [{
  161. key: '{%d}',
  162. type: 'day',
  163. count: 86400
  164. }, {
  165. key: '{%h}',
  166. type: 'hour',
  167. count: 3600
  168. }, {
  169. key: '{%m}',
  170. type: 'minute',
  171. count: 60
  172. }, {
  173. key: '{%s}',
  174. type: 'second',
  175. count: 1,
  176. }];
  177. let diffSecond = countDownTime;
  178. formatType.forEach(format => {
  179. const index = this._findTimeName(fomatArray, format.key);
  180. if (index === -1) return;
  181. const name = fomatArray[index];
  182. const formatItem = {
  183. type: format.type,
  184. name,
  185. value: parseInt(diffSecond / format.count)
  186. };
  187. if (this.data.isZeroPadd) {
  188. formatItem.value = this.zeroPadding(formatItem.value);
  189. }
  190. diffSecond %= format.count;
  191. date.push(formatItem);
  192. });
  193. this.setData({
  194. date
  195. });
  196. return date;
  197. },
  198. _findTimeName(fomatArray, str) {
  199. const index = fomatArray.indexOf(str);
  200. if (index === -1) return -1;
  201. return index + 1;
  202. },
  203. CountdownEnd() {
  204. this.triggerEvent('linend', {});
  205. },
  206. }
  207. });