效果如下:
思路:
通过标签的data-time-end和data-time-start来获取倒计时的结束和开始时间(开始时间可传可不传)
调用counter方法时需传入{callback:function(回调函数来接收状态和时间间隔), countbeforeStart: Boolean(是否需要开始倒计时,不传默认不需要开始倒计时)}
如果有开始时间,则开始时间必须小于结束时间,否则弹出警告
再判断开始时间是否大于现在的时间,如果大于则活动未开始,
如果需要开始倒计时则通过setInterval倒计时开始时间(每隔50ms计算一次开始结束时间和现在时间的间隔,当发现间隔时间有变化则调用回调函数),当计算到活动开始时间小于或等于现在的时间时清空定时器(clearInterval),然后重新绑定click方法
如果不需要开始倒计时则调用回调函数,并用return停止执行后面的代码
如果活动已开始则接着判断活动结束时间是否大于现在的时间,如果大于则通过setInterval倒计时结束时间(每隔50ms计算一次活动结束时间和现在时间的间隔,当发现间隔时间有变化则调用回调函数),当活动结束时间小于或等于现在的时间时清空定时器并调用回调函数
如果活动结束时间小于或等于现在的时间,则活动结束,调用回调函数
每次调用回调函数都需传入state(-1为已结束,0为进行中,1为未开始),{day, hour, minute, second}(间隔日,时,分,秒)
示例代码:
CSS:
ul{width:400px; margin:auto; text-align:center;} ul li{list-style:none; height:150px; border-radius:15px; box-shadow:0 5px 15px rgba(0,0,0,0.2); margin:30px; line-height:60px; background: lightblue;}
HTML:
<ul> <li data-end-time="2020-10-31 14:41"></li> <li data-end-time="2025-11-01 12:40" data-start-time="2020-10-31 17:02"></li> <li data-end-time="2017-10-30 12:40" data-start-time="2017-10-28 16:58"></li> </ul> <script id="jquery_183" type="text/javascript" class="library" src="http://code.jquery.com/jquery-latest.jss"></script>
JS:
;(function($){ $.fn.counter=function(options){ //获取日时分秒 var getTimeSeperation = function(time){ var day = Math.floor(time/(24*3600)); var lessSecond = time-(day*24*3600); var hour = Math.floor(lessSecond/3600); lessSecond = lessSecond-hour*3600; var minute = Math.floor(lessSecond/60); var second = Math.floor(lessSecond-minute*60); return { day: day < 10 ? '0' + day : day, hour: hour < 10 ? '0' + hour : hour, minute: minute < 10 ? '0' + minute : minute, second: second < 10 ? '0' + second : second } } //获取时间对象 var getTime = function(time){ return time instanceof Date ? time.getTime() : new Date(time).getTime() } //获取距离现在的时间 var getTimeFromNow = function(time){ return Math.floor((time - new Date().getTime()) / 1000) } !options.callback && alert('请传回调函数!') this.each(function(){ var self = this; this.endTime = $(this).attr('data-end-time'); this.startTime = $(this).attr('data-start-time'); this.callback = options.callback; if(!this.endTime){ alert('请传入结束时间'); return; } this.endTime = getTime(this.endTime); if(this.startTime){ this.startTime = getTime(this.startTime); if(this.endTime < this.startTime){ alert('活动开始时间不能小于结束时间'); return; } this.timeFromNow = getTimeFromNow(this.startTime); this.newTimeFromNow = this.timeFromNow; if(this.timeFromNow > 0){ //活动未开始 if(options.countbeforeStart){ //需要倒数开始时间 this.interval = setInterval(function(){ self.newTimeFromNow = getTimeFromNow(self.startTime); if(self.newTimeFromNow !== self.timeFromNow){ if(self.newTimeFromNow > 0){ //活动即将开始 self.callback(1, getTimeSeperation(self.newTimeFromNow)); self.timeFromNow = self.newTimeFromNow; }else{ //活动已开始 clearInterval(self.interval); $(self).counter({callback:self.callback}) } } },50) }else{ this.callback(1, getTimeSeperation(this.timeFromNow)) } return; } } this.timeFromNow = getTimeFromNow(this.endTime); this.newTimeFromNow = this.timeFromNow; if(this.newTimeFromNow > 0){ this.interval = setInterval(function(){ self.newTimeFromNow = getTimeFromNow(self.endTime); if(self.newTimeFromNow !== self.timeFromNow){ if(self.newTimeFromNow > 0){ //活动进行中 self.callback(0, getTimeSeperation(self.newTimeFromNow)); self.timeFromNow = self.newTimeFromNow; }else{ //活动已结束 clearInterval(self.counter); self.callback(-1, getTimeSeperation(self.newTimeFromNow)); } } },50) }else{ //活动已结束 this.callback(-1, getTimeSeperation(self.newTimeFromNow)); } }); return this; } })(jQuery) //调用方式 window.onload = function(){ $('ul li').counter({ callback: function(state, {day, hour, minute, second}){ if(state === -1){ //活动已结束 this.innerHTML = '活动已结束'; }else if(state === 1){ //活动未开始 var startTime = new Date($(this).attr('data-start-time')).toString(); this.innerHTML = `活动将于${startTime}开始<br>距离活动开始还有${day}天${hour}时${minute}分${second}秒`; }else{ //活动进行中 this.innerHTML = `距离活动结束还有${day}天${hour}时${minute}分${second}秒`; } }, countbeforeStart: true//是否需要开始倒计时(不传默认不需要开始倒计时) }) } /**** 公用方法 ****/ //日期格式转换 Date.prototype.toString = function (f) { function tempfunc(opo, pos) { var val = ''; opo = String(opo); for (var a = 1; a < arguments.length; a++) { var chr = opo.charAt(arguments[a] - 1); val += chr; } return val; } if (!f) f = 'yyyy-MM-dd HH:mm:ss'; var h12 = this.getHours() > 12 ? (this.getHours() - 12) : this.getHours(); var tmp = { 'yyyy': this.getFullYear(), 'yy': tempfunc(this.getFullYear(), 3, 4), 'MM': (this.getMonth() < 9 ? '0' : '') + (this.getMonth() + 1), 'M': this.getMonth() + 1, 'dd': (this.getDate() < 10 ? '0' : '') + this.getDate(), 'd': this.getDate(), 'hh': (h12 < 10 ? '0' : '') + h12, // 12小时制 'h': h12, 'HH': (this.getHours() < 10 ? '0' : '') + this.getHours(), // 24小时制 'H': this.getHours(), 'mm': (this.getMinutes() < 10 ? '0' : '') + this.getMinutes(), 'm': this.getMinutes(), 'ss': (this.getSeconds() < 10 ? '0' : '') + this.getSeconds(), 's': this.getSeconds() }; for (var p in tmp) f = f.replace(new RegExp('\b' + p + '\b', 'g'), tmp[p]); return f; }; /**** 公用方法 ****/
在线演示:http://sandbox.runjs.cn/show/s1ae8bm9