<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>倒计时-多种格式调用-原生js封装</title>
<link rel="shortcut icon" href="../public/image/favicon.ico" type="images/x-icon"/>
<link rel="icon" href="../public/image/favicon.png" type="images/png"/>
<link rel="stylesheet" type="text/css" href="../public/style/cssreset-min.css">
<link rel="stylesheet" type="text/css" href="../public/style/common.css">
<style type="text/css">
/*公共*/
html{
height:100%;
}
body, div, dl, dt, dd, ul, ol, li, h2, h3, h4, h5, h6, h7, pre, code, form, fieldset, legend, input, textarea, p, blockquote, th, td {
margin: 0;
padding: 0
}
ol, ul {
list-style: none
}
body{
position: relative;
min-height:100%;
font-size:14px;
font-family: Tahoma, Verdana,"Microsoft Yahei";
color:#333;
}
a{
text-decoration: none;
color:#333;
}
.header{
width: 960px;
padding-top: 15px;
margin: 0 auto;
line-height: 30px;
text-align: right;
}
.header a{
margin: 0 5px;
}
.main{
width:960px;
margin: 50px auto 0;
}
.code{
border:1px dashed #e2e2e2;
padding:10px 5px;
margin-bottom:25px;
}
pre {
font-family: "Microsoft Yahei",Arial,Helvetica;
white-space: pre-wrap; /*css-3*/
white-space: -moz-pre-wrap; /*Mozilla,since1999*/
white-space: -pre-wrap; /*Opera4-6*/
white-space: -o-pre-wrap; /*Opera7*/
word-wrap: break-word; /*InternetExplorer5.5+*/
}
.example{
padding-top:40px;
margin-bottom:90px;
}
.example .call{
padding:18px 5px;
background:#f0f5f8;
}
.example h3{
padding-top:20px;
margin-bottom:7px;
}
.example table {
width:100%;
table-layout:fixed;
border-collapse: collapse;
border-spacing: 0;
border: 1px solid #cee1ee;
border-left: 0;
}
.example thead {
border-bottom: 1px solid #cee1ee;
background-color: #e3eef8;
}
.example tr {
line-height: 24px;
font-size: 13px;
}
.example tr:nth-child(2n) {
background-color: #f0f5f8;
}
.example tr th,.example tr td {
border-left: 1px solid #cee1ee;
word-break: break-all;
word-wrap: break-word;
padding:0 10px;
font-weight: normal;
}
.example tr th {
color: #555;
padding-top: 2px;
padding-bottom: 2px;
text-align: left;
}
/*公共*/
.countdown {
margin-bottom: 15px;
}
</style>
<script type="text/javascript">
/*封装代码*/
(function() {
var Countdown = function(el, opts) {
var self = this;
var defaults = {
'format': 'hh:mm:ss', //格式
'endtime': '', //结束时间
'interval': 1000, //多久倒计时一次 单位:ms
'starttime':r(el)[0].innerHTML, //开始时间
'countEach': function(time) { //每单位时间出发事件,传入一个对象,包含时间信息(month)和时间格式化输出(format)
r(el)[0].innerHTML=time['format']
},
'countEnd':function (time) {} //倒计时结束回调事件
}
opts = opts || {};
for (var w in defaults) {
if ("undefined" == typeof opts[w]) {
opts[w] = defaults[w];
}
}
this.params = opts;
this.container = r(el);
if (this.container.length > 1) {
var x = [];
return this.container.each(function() {
x.push(new Countdown(this, opts))
}), x
}
this._hander=null;
this._start=0;
this._end=0;
this.isTimestamp = isNaN(this.params.starttime)||isNaN(this.params.endtime);//是否为秒计数模式
this.init();
}
Countdown.prototype = {
//初始化
init: function() {
var self = this;
this.reset();
},
reset:function(){
var self = this;
if (this.isTimestamp) {
this._start = this.params.starttime ? this.getTimestamp(this.params.starttime) : (+new Date());
this._end = this.getTimestamp(this.params.endtime);
} else {
this._start = this.params.starttime * 1e3;
this._end = this.params.endtime * 1e3;
}
this.count();
},
count:function(){
var self = this;
this._hander = setInterval(function(){
self._start-=self.params.interval;
self.params.countEach(self.getTime(self._start));
if(self._start<=self._end){
clearInterval(self._hander);
self.params.countEnd();
}
},self.params.interval);
},
//获取时间戳
getTimestamp:function(str){
return +new Date(str)||+new Date('1970/1/1 '+str);
},
timeFormat:function(fmt,timestamp){
var date = new Date(timestamp);
var o = {
"M+" : date.getMonth()+1, //月份
"d+" : date.getDate(), //日
"h+" : date.getHours(), //小时
"m+" : date.getMinutes(), //分
"s+" : date.getSeconds(), //秒
"q+" : Math.floor((date.getMonth()+3)/3), //季度
"S" : date.getMilliseconds() //毫秒
};
if(/(y+)/.test(fmt)){
fmt=fmt.replace(RegExp.$1, (date.getFullYear()+"").substr(4 - RegExp.$1.length));
}
for(var k in o){
if(new RegExp("("+ k +")").test(fmt)){
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
}
}
return fmt;
},
getTime: function(timestamp) {
var self = this;
var date, format;
if (this.isTimestamp) {
date = new Date(timestamp);
format = self.timeFormat(self.params.format, timestamp);
} else {
date = new Date();
format = timestamp / 1e3;
}
return {
'year': date.getFullYear(),
'month': date.getMonth() + 1,
'day': date.getDate(),
'hour': date.getHours(),
'minute': date.getMinutes(),
'second': date.getSeconds(),
'quarter': Math.floor((date.getMonth() + 3) / 3),
'microsecond': date.getMilliseconds(),
'format': format
};
}
}
var r = (function() {
var e = function(e) {
var a = this,
t = 0;
for (t = 0; t < e.length; t++) {
a[t] = e[t];
}
return a.length = e.length, this
};
e.prototype = {
addClass: function(e) {
if ("undefined" == typeof e) return this;
for (var a = e.split(" "), t = 0; t < a.length; t++)
for (var r = 0; r < this.length; r++) this[r].classList.add(a[t]);
return this
},
each: function(e) {
for (var a = 0; a < this.length; a++) e.call(this[a], a, this[a]);
return this
},
html: function(e) {
if ("undefined" == typeof e) return this[0] ? this[0].innerHTML : void 0;
for (var a = 0; a < this.length; a++) this[a].innerHTML = e;
return this
},
find: function(a) {
for (var t = [], r = 0; r < this.length; r++)
for (var i = this[r].querySelectorAll(a), s = 0; s < i.length; s++) t.push(i[s]);
return new e(t)
},
append: function(a) {
var t, r;
for (t = 0; t < this.length; t++)
if ("string" == typeof a) {
var i = document.createElement("div");
for (i.innerHTML = a; i.firstChild;) this[t].appendChild(i.firstChild)
} else if (a instanceof e)
for (r = 0; r < a.length; r++) this[t].appendChild(a[r]);
else this[t].appendChild(a);
return this
},
}
var a = function(a, t) {
var r = [],
i = 0;
if (a && !t && a instanceof e) {
return a;
}
if (a) {
if ("string" == typeof a) {
var s, n, o = a.trim();
if (o.indexOf("<") >= 0 && o.indexOf(">") >= 0) {
var l = "div";
for (0 === o.indexOf("<li") && (l = "ul"), 0 === o.indexOf("<tr") && (l = "tbody"), (0 === o.indexOf("<td") || 0 === o.indexOf("<th")) && (l = "tr"), 0 === o.indexOf("<tbody") && (l = "table"), 0 === o.indexOf("<option") && (l = "select"), n = document.createElement(l), n.innerHTML = a, i = 0; i < n.childNodes.length; i++) r.push(n.childNodes[i])
} else
for (s = t || "#" !== a[0] || a.match(/[ .<>:~]/) ? (t || document).querySelectorAll(a) : [document.getElementById(a.split("#")[1])], i = 0; i < s.length; i++) s[i] && r.push(s[i])
} else if (a.nodeType || a === window || a === document) {
r.push(a);
} else if (a.length > 0 && a[0].nodeType) {
for (i = 0; i < a.length; i++) {
r.push(a[i]);
}
}
}
return new e(r)
};
return a;
}())
window.countdown = Countdown;
})()
/*封装代码*/
</script>
</head>
<body>
<div class="header">
<a href="https://github.com/huanghanzhilian/widget" target="_blank">项目地址</a>
<a href="/widget/">返回首页</a>
</div>
<div class="main">
<div class="countdown">
<p>#例子1# 12:00:00到11:50:00</p>
<p id="countdown" class="">12:00:00</p>
</div>
<script type="text/javascript">
new countdown("#countdown", {
endtime: '11:50:00'
});
</script>
<div class="code">
<p>
endtime: '11:50:00',设置结束时间/默认值为空||0,执行其他默认参数
</p>
<p>new countdown("#countdown", {
endtime: '11:50:00'
});</p>
</div>
<div class="countdown">
<p>#例子2# 60到50</p>
<p id="countdown1" class="">60</p>
</div>
<script type="text/javascript">
new countdown("#countdown1", {
endtime: '50',
countEnd: function() {
alert("结束")
}
});
</script>
<div class="code">
<p>
countEnd: 'function',设置结束倒计时后触发的函数/默认值为空,执行其他默认参数
</p>
<p>new countdown("#countdown1", {
endtime: '50',
countEnd: function() {
alert("结束")
}
});</p>
</div>
<div class="countdown">
<p>#例子3# 60到0</p>
<p id="countdown2" class=""></p>
</div>
<script type="text/javascript">
new countdown("#countdown2", {
starttime:'60'
});
</script>
<div class="code">
<p>
starttime:'60',设置开始时间/默认值为元素内容,执行其他默认参数
</p>
<p>new countdown("#countdown2", {
starttime:'60'
});</p>
</div>
<div class="countdown">
<p>#例子4# 2017/01/11,11:00:00到1970/1/1</p>
<p id="countdown3" class="">2017/01/11,11:00:00</p>
</div>
<script type="text/javascript">
new countdown("#countdown3", {
format:'yy:MM:dd:hh:mm:ss'
});
</script>
<div class="code">
<p>
format:'yy:MM:dd:hh:mm:ss',格式化输出的时间格式/默认值为'hh:mm:ss',执行其他默认参数
</p>
<p>new countdown("#countdown3", {
format:'yy:MM:dd:hh:mm:ss'
});</p>
</div>
<div class="example">
<div class="call">
<h2>调用方法:</h2>
<p>new countdown(selector,{options});</p>
</div>
<h3>options参数</h3>
<table>
<thead>
<tr>
<th width="150">参数</th>
<th width="100">默认值</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>format</td>
<td>'hh:mm:ss'</td>
<td>格式化输出的时间格式,年(y)、月(M)、日(d)、小时(h)、分(m)、秒(s)、毫秒(S)、季度(q)</td>
</tr>
<tr>
<td>starttime</td>
<td>''</td>
<td>开始时间</td>
</tr>
<tr>
<td>endtime</td>
<td>''</td>
<td>结束时间</td>
</tr>
<tr>
<td>interval</td>
<td>1000</td>
<td>计数的时间间隔(单位:毫秒)</td>
</tr>
<tr>
<td>countEach(time)</td>
<td>[时间格式化输出]</td>
<td>每计时单位执行,其中time包含时间信息:year年、quarter季度、month月、day日、hour小时、minute分钟、second秒、microsecond毫秒、format格式化输出</td>
</tr>
<tr>
<td>countEnd(time)</td>
<td>[时间格式化输出]</td>
<td>计时结束后执行,其中time包含时间信息:year年、quarter季度、month月、day日、hour小时、minute分钟、second秒、microsecond毫秒、format格式化输出</td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>