快过年了,还有几天过年啊?天天看日历,所以,自己写了个日历选择器玩玩!
直接上代码:
表现层
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #nickCalendar {
2 250px;
3 padding: 10px;
4 text-align: center;
5 background-color: springgreen;
6 margin: auto;
7 border-radius: 10px;
8 }
9
10 .nick-calendar-tit {
11 168px;
12 margin: auto;
13 color: midnightblue;
14 }
15
16 .nick-calendar-tit span {
17 float: left;
18 20px;
19 font-size: 14px;
20 height: 20px;
21 line-height: 20px;
22 text-align: center;
23 margin: 2px;
24 font-weight: bold;
25 }
26
27 .nick-calendar-bd {
28 168px;
29 padding: 10px;
30 background-color: pink;
31 margin: auto;
32 border-radius: 10px;
33 }
34
35 .clear:after {
36 content: '';
37 display: block;
38 height: 0;
39 clear: both;
40 }
41
42 .nick-calendar-bd span {
43 20px;
44 font-size: 14px;
45 height: 20px;
46 line-height: 20px;
47 text-align: center;
48 margin: 2px;
49 float: left;
50 cursor: pointer;
51 border-radius: 50%;
52 }
53
54 .prev-date-nick, .next-date-nick {
55 background-color: #999;
56 }
57
58 .nick-calendar-hd {
59 height: 30px;
60 line-height: 30px;
61 font-weight: bold;
62 }
63
64 .nick-calendar-prev, .nick-calendar-next {
65 background-color: violet;
66 border: 0;
67 border-radius: 5px;
68 font-weight: bold;
69 }
70
71 .nick-calendar-prev-year, .nick-calendar-next-year {
72 background-color: turquoise;
73 border: 0;
74 border-radius: 5px;
75 font-weight: bold;
76 }
77
78 .nick-calendar-date {
79 display: inline-block;
80 90px;
81 }
82
83 .date-nick {
84 background-color: violet;
85 }
86
87 .nick-calendar-current {
88 background-color: yellowgreen;
89 }
温馨提示:
这点样式必须的哦,不然,呵呵!当然,你也可以自定义!
结构层
<input type="text" placeholder="请选择" readonly id="date1">
结构层只需您一个触发容器input即可!
行为层
参数存在一个对象中
var opt = {//参数保存在此对象中
opts: options
};
所有的方法保存在另一个对象中
var obj = {}
填充日历方法
fillDate: function (year, month) {}
本月份第一天是星期几-为显示上个月的天数做铺垫
var first_day = new Date(year, month, 1).getDay();
如果刚好是星期天,则空出一行(显示上个月的天数)
first_day = first_day == 0 ? 7 : first_day;
本月份最后一天是几号
var final_date = new Date(year, month + 1, 0).getDate(),
上个月的最后一天是几号
last_date = new Date(year, month, 0).getDate(),
剩余的格子数--即排在末尾的格子数
surplus = 42 - first_day - final_date;
设置表头的日历
opt.oHeadDate.innerHTML = year + '年' + (month + 1) + '月';
填充日历内容
var html = '';
//上个月的显示天数
for (var i = 0; i < first_day; i++) {
html += '<span class="prev-date-nick">' + (last_date - (first_day - 1) + i) + '</span>';
}
//本月的显示天数
for (var j = 0; j < final_date; j++) {
html += '<span class="date-nick">' + (j + 1) + '</span>';
}
//下个月的显示天数
for (var k = 0; k < surplus; k++) {
html += '<span class="next-date-nick">' + (k + 1) + '</span>';
}
//fill
opt.oBody.innerHTML = html;
设置当天样式
if (year == new Date().getFullYear() && month == new Date().getMonth()) {
opt.oBody.getElementsByTagName('span')[first_day + opt.date - 1].className = 'nick-calendar-current date-nick';
}
点击赋值ipt得到日期
for (var x = 0, v = opt.oBody.getElementsByTagName('span'), len = v.length; x < len; x++) {
v[x].onclick = function () {
var now = new Date(year, month, 1), y = 0, m = 0;
if (this.className.indexOf('prev-date-nick') > -1) {
y = new Date(now.setMonth(now.getMonth() - 1)).getFullYear();
m = new Date(now).getMonth();
} else if (this.className.indexOf('next-date-nick') > -1) {
y = new Date(now.setMonth(now.getMonth() + 1)).getFullYear();
m = new Date(now).getMonth();
} else if (this.className.indexOf('date-nick') > -1) {
y = year;
m = month;
}
document.getElementById('date1').value = y + '-' + (m + 1) + '-' + this.innerHTML;
opt.oWrap.style.display = 'none';//隐藏日历容器
}
}
下个月
就是设置月份加一即可。
next: function () {
var me = this;
opt.oNext.onclick = function () {
opt.month++;
if (opt.month > 11) {
opt.month = 0;
opt.year++;
}
// 填充日历
me.fillDate(opt.year, opt.month);
}
},
上个月
就是设置月份减一即可。
prev: function () {
var me = this;
opt.oPrev.onclick = function () {
opt.month--;
if (opt.month < 0) {
opt.month = 11;
opt.year--;
}
// 填充日历
me.fillDate(opt.year, opt.month);
}
},
下一年
就是设置年份加一即可。
nextYear: function () {
var me = this;
opt.oNextYear.onclick = function () {
opt.year++;
// 填充日历
me.fillDate(opt.year, opt.month);
}
},
上一年
就是设置年份减一即可。
prevYear: function () {
var me = this;
opt.oPrevYear.onclick = function () {
if (opt.year > 1970) {
opt.year--;
}
// 填充日历
me.fillDate(opt.year, opt.month);
}
},
获取元素偏移位置
offset: function (ele) {
var l = ele.offsetLeft, t = ele.offsetTop, p = ele.offsetParent;
while (p) {
l += p.offsetLeft + p.clientLeft;
t += p.offsetTop + p.clientTop;
p = p.offsetParent;
}
return {left: l, top: t}
},
用于设置日历容器样式定位。
初始化
init: function () {//初始化
}
初始化参数,创建日历容器固定结构,每次切换日期值即可
var div = document.createElement("DIV");
div.setAttribute('id', opt.opts.wrapId);
div.innerHTML = '<div class="nick-calendar-hd"><button class="nick-calendar-prev-year"><<</button>' +
'<button class="nick-calendar-prev"><</button><span class="nick-calendar-date"></span>' +
'<button class="nick-calendar-next">></button><button class="nick-calendar-next-year">>></button>' +
'</div><div class="nick-calendar-tit clear">' +
'<span>日</span><span>一</span><span>二</span><span>三</span><span>四</span><span>五</span><span>六</span>' +
'</div><div class="nick-calendar-bd clear"></div>';
document.getElementsByTagName("body")[0].appendChild(div);
opt.oWrap = document.getElementById(opt.opts.wrapId);//日历容器
opt.trigger = document.getElementById(opt.opts.triggerId);//触发容器
opt.oHeadDate = opt.oWrap.getElementsByClassName('nick-calendar-date')[0];//头部日期
opt.oBody = opt.oWrap.getElementsByClassName('nick-calendar-bd')[0];//日期容器
opt.oTit = opt.oWrap.getElementsByClassName('nick-calendar-tit')[0];//星期容器
opt.oPrev = opt.oWrap.getElementsByClassName('nick-calendar-prev')[0];//上月按钮
opt.oNext = opt.oWrap.getElementsByClassName('nick-calendar-next')[0];//下月按钮
opt.oPrevYear = opt.oWrap.getElementsByClassName('nick-calendar-prev-year')[0];//上月按钮
opt.oNextYear = opt.oWrap.getElementsByClassName('nick-calendar-next-year')[0];//下月按钮
opt.year = 0;//年
opt.month = 0;//月
opt.date = 0;//日
获取今天的日历时间
var now = new Date();
opt.year = now.getFullYear();
opt.month = now.getMonth();
opt.date = now.getDate();
初始化--填充日历
this.fillDate(opt.year, opt.month);
切换年月方法
this.next();
this.nextYear();
this.prev();
this.prevYear();
设置日历容器位置
opt.oWrap.style.position = 'absolute';
opt.oWrap.style.left = this.offset(opt.trigger).left + opt.trigger.offsetWidth + 10 + 'px';
opt.oWrap.style.top = this.offset(opt.trigger).top + 'px';
opt.oWrap.style.display = 'none';//默认隐藏日历容器
input触发日历选择
opt.trigger.onclick = function () {
opt.oWrap.style.display = 'block';
}
初始化调用
obj.init();//初始化
定义日历选择方法
function calendarNick(options) {
var opt = {//参数保存在此对象中
opts: options
};
var obj={
//code
};
}
定义一个日历选择器方法把2个对象包裹起来,并调用初始化方法即可。
调用日历选择器
调用时,两个必传的容器id参数。
calendarNick({
wrapId: 'nickCalendar',//日历容器id
triggerId: 'date1'//触发容器id
});
完整代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="UTF-8">
5 <title>calendar-nick</title>
6 <style>
7 #nickCalendar {
8 250px;
9 padding: 10px;
10 text-align: center;
11 background-color: springgreen;
12 margin: auto;
13 border-radius: 10px;
14 }
15
16 .nick-calendar-tit {
17 168px;
18 margin: auto;
19 color: midnightblue;
20 }
21
22 .nick-calendar-tit span {
23 float: left;
24 20px;
25 font-size: 14px;
26 height: 20px;
27 line-height: 20px;
28 text-align: center;
29 margin: 2px;
30 font-weight: bold;
31 }
32
33 .nick-calendar-bd {
34 168px;
35 padding: 10px;
36 background-color: pink;
37 margin: auto;
38 border-radius: 10px;
39 }
40
41 .clear:after {
42 content: '';
43 display: block;
44 height: 0;
45 clear: both;
46 }
47
48 .nick-calendar-bd span {
49 20px;
50 font-size: 14px;
51 height: 20px;
52 line-height: 20px;
53 text-align: center;
54 margin: 2px;
55 float: left;
56 cursor: pointer;
57 border-radius: 50%;
58 }
59
60 .prev-date-nick, .next-date-nick {
61 background-color: #999;
62 }
63
64 .nick-calendar-hd {
65 height: 30px;
66 line-height: 30px;
67 font-weight: bold;
68 }
69
70 .nick-calendar-prev, .nick-calendar-next {
71 background-color: violet;
72 border: 0;
73 border-radius: 5px;
74 font-weight: bold;
75 }
76
77 .nick-calendar-prev-year, .nick-calendar-next-year {
78 background-color: turquoise;
79 border: 0;
80 border-radius: 5px;
81 font-weight: bold;
82 }
83
84 .nick-calendar-date {
85 display: inline-block;
86 90px;
87 }
88
89 .date-nick {
90 background-color: violet;
91 }
92
93 .nick-calendar-current {
94 background-color: yellowgreen;
95 }
96
97 </style>
98 </head>
99 <body>
100 <input type="text" placeholder="请选择" readonly id="date1">
101 <script>
102 // 调用
103 calendarNick({
104 wrapId: 'nickCalendar',//日历容器id
105 triggerId: 'date1'//触发容器id
106 });
107 //日历选择功能
108 function calendarNick(options) {
109 var opt = {//参数保存在此对象中
110 opts: options
111 };
112
113 var obj = {
114 //填充日历
115 fillDate: function (year, month) {
116 //本月份第一天是星期几-为显示上个月的天数做铺垫
117 var first_day = new Date(year, month, 1).getDay();
118 //如果刚好是星期天,则空出一行(显示上个月的天数)
119 first_day = first_day == 0 ? 7 : first_day;
120 //本月份最后一天是几号
121 var final_date = new Date(year, month + 1, 0).getDate(),
122 //上个月的最后一天是几号
123 last_date = new Date(year, month, 0).getDate(),
124 //剩余的格子数--即排在末尾的格子数
125 surplus = 42 - first_day - final_date;
126 /*设置表头的日历*/
127 opt.oHeadDate.innerHTML = year + '年' + (month + 1) + '月';
128 /*填充日历执行*/
129 var html = '';
130 //上个月的显示天数
131 for (var i = 0; i < first_day; i++) {
132 html += '<span class="prev-date-nick">' + (last_date - (first_day - 1) + i) + '</span>';
133 }
134 //本月的显示天数
135 for (var j = 0; j < final_date; j++) {
136 html += '<span class="date-nick">' + (j + 1) + '</span>';
137 }
138 //下个月的显示天数
139 for (var k = 0; k < surplus; k++) {
140 html += '<span class="next-date-nick">' + (k + 1) + '</span>';
141 }
142 //fill
143 opt.oBody.innerHTML = html;
144 // 当天
145 if (year == new Date().getFullYear() && month == new Date().getMonth()) {
146 opt.oBody.getElementsByTagName('span')[first_day + opt.date - 1].className = 'nick-calendar-current date-nick';
147 }
148
149 //点击赋值ipt得到日期
150 for (var x = 0, v = opt.oBody.getElementsByTagName('span'), len = v.length; x < len; x++) {
151 v[x].onclick = function () {
152 var now = new Date(year, month, 1), y = 0, m = 0;
153 if (this.className.indexOf('prev-date-nick') > -1) {
154 y = new Date(now.setMonth(now.getMonth() - 1)).getFullYear();
155 m = new Date(now).getMonth();
156 } else if (this.className.indexOf('next-date-nick') > -1) {
157 y = new Date(now.setMonth(now.getMonth() + 1)).getFullYear();
158 m = new Date(now).getMonth();
159 } else if (this.className.indexOf('date-nick') > -1) {
160 y = year;
161 m = month;
162 }
163 document.getElementById('date1').value = y + '-' + (m + 1) + '-' + this.innerHTML;
164 opt.oWrap.style.display = 'none';//隐藏日历容器
165 }
166 }
167 },
168 // 下个月
169 next: function () {
170 var me = this;
171 opt.oNext.onclick = function () {
172 opt.month++;
173 if (opt.month > 11) {
174 opt.month = 0;
175 opt.year++;
176 }
177 // 填充日历
178 me.fillDate(opt.year, opt.month);
179 }
180
181 },
182 // 上个月
183 prev: function () {
184 var me = this;
185 opt.oPrev.onclick = function () {
186 opt.month--;
187 if (opt.month < 0) {
188 opt.month = 11;
189 opt.year--;
190 }
191 // 填充日历
192 me.fillDate(opt.year, opt.month);
193 }
194
195 },
196 // 下一年
197 nextYear: function () {
198 var me = this;
199 opt.oNextYear.onclick = function () {
200 opt.year++;
201 // 填充日历
202 me.fillDate(opt.year, opt.month);
203 }
204
205 },
206 // 上一年
207 prevYear: function () {
208 var me = this;
209 opt.oPrevYear.onclick = function () {
210 if (opt.year > 1970) {
211 opt.year--;
212 }
213 // 填充日历
214 me.fillDate(opt.year, opt.month);
215 }
216
217 },
218 //获取元素偏移位置
219 offset: function (ele) {
220 var l = ele.offsetLeft, t = ele.offsetTop, p = ele.offsetParent;
221 while (p) {
222 l += p.offsetLeft + p.clientLeft;
223 t += p.offsetTop + p.clientTop;
224 p = p.offsetParent;
225 }
226 return {left: l, top: t}
227 },
228 init: function () {//初始化
229 // 初始化参数
230 //创建日历容器固定结构,每次切换日期值即可
231 var div = document.createElement("DIV");
232 div.setAttribute('id', opt.opts.wrapId);
233 div.innerHTML = '<div class="nick-calendar-hd"><button class="nick-calendar-prev-year"><<</button>' +
234 '<button class="nick-calendar-prev"><</button><span class="nick-calendar-date"></span>' +
235 '<button class="nick-calendar-next">></button><button class="nick-calendar-next-year">>></button>' +
236 '</div><div class="nick-calendar-tit clear">' +
237 '<span>日</span><span>一</span><span>二</span><span>三</span><span>四</span><span>五</span><span>六</span>' +
238 '</div><div class="nick-calendar-bd clear"></div>';
239 document.getElementsByTagName("body")[0].appendChild(div);
240 opt.oWrap = document.getElementById(opt.opts.wrapId);//日历容器
241 opt.trigger = document.getElementById(opt.opts.triggerId);//触发容器
242 opt.oHeadDate = opt.oWrap.getElementsByClassName('nick-calendar-date')[0];//头部日期
243 opt.oBody = opt.oWrap.getElementsByClassName('nick-calendar-bd')[0];//日期容器
244 opt.oTit = opt.oWrap.getElementsByClassName('nick-calendar-tit')[0];//星期容器
245 opt.oPrev = opt.oWrap.getElementsByClassName('nick-calendar-prev')[0];//上月按钮
246 opt.oNext = opt.oWrap.getElementsByClassName('nick-calendar-next')[0];//下月按钮
247 opt.oPrevYear = opt.oWrap.getElementsByClassName('nick-calendar-prev-year')[0];//上月按钮
248 opt.oNextYear = opt.oWrap.getElementsByClassName('nick-calendar-next-year')[0];//下月按钮
249 opt.year = 0;//年
250 opt.month = 0;//月
251 opt.date = 0;//日
252
253 // 获取今天的日历时间
254 var now = new Date();
255 opt.year = now.getFullYear();
256 opt.month = now.getMonth();
257 opt.date = now.getDate();
258 // 初始化--填充日历
259 this.fillDate(opt.year, opt.month);
260 //切换年月
261 this.next();
262 this.nextYear();
263 this.prev();
264 this.prevYear();
265 //设置日历容器位置
266 opt.oWrap.style.position = 'absolute';
267 opt.oWrap.style.left = this.offset(opt.trigger).left + opt.trigger.offsetWidth + 10 + 'px';
268 opt.oWrap.style.top = this.offset(opt.trigger).top + 'px';
269 opt.oWrap.style.display = 'none';//默认隐藏日历容器
270 //ipt触发日历选择
271 opt.trigger.onclick = function () {
272 opt.oWrap.style.display = 'block';
273 }
274 }
275 };
276 obj.init();//初始化
277 }
278
279 </script>
280 </body>
281 </html>
over!注释加代码应该一看就懂了。复制完整代码,试试吧!
周公找我了,see you!