在开始之前我们先复习一下javascript的Date对象,这是一个内置对象,它包含了一系列方法供我们操作。按功能可以分为以下三大类:
注:用getYear()返回的数并不一定是4位的!处于1900年和1999年间的getYear()方法返回的只有两位数。在此之前的或是在此之后的年份返回的都是四位数的。getYear()方法不应该再使用了。推荐使用getFullYear方法。另,javascript也提系列基于世界时的时间设置函数,如 getUTCDate(),getUTCDay(),getUTCFullYear(),getUTCHours(),getUTCMilliSeconds(),getUTCMinutes(),getUTCMonth ()与getUTCSeconds()方法。
1.
/********根据一个日期求得星期,如'2009-6-21' return 0(星期日)***********/
2.
var
get_day =
function
(strDate){
3.
var
f = strDate.replace(/-/g,
'/'
);
4.
f =
new
Date(f).getDay();
5.
return
"星期"
+
"天一二三四五六"
.split(
''
)[f]
6.
}
7.
alert(get_day(
'2009-7-25'
))
注,由于javascript是从0开始的,因此需要对月份进行操作时要加1 .
参数 | 描述 |
---|---|
month | 必需。一个表示月份的数值,该值介于 0(一月) ~ 11(十二月) 之间。 |
day | 可选。一个表示月的某一天的数值,该值介于 1 ~ 31 之间(以本地时间计)。在 EMCAScript 标准化之前,不支持该参数。 |
1.
var
now =
new
Date()
2.
var
currentMonth = now.getMonth() -1
//获得当前的月份
3.
var
nextMonth = now.getMonth()
//获得下一个月的月份
1.
//用javascript取得某一年的第一个星期一的日期
2.
function
get(year) {
3.
var
d =
new
Date(year, 1, 1);
4.
var
day = d.getDay();
//获取1月1号是星期几
5.
d.setDate((8 - day) % 7 + 1);
6.
return
d;
7.
}
01.
//求前 n 天或者后 n 天的日期(用xxxx-xx-xx表示)
02.
var
showdate =
function
(n){
03.
var
d =
new
Date();
04.
d.setDate(d.getDate()+n);
05.
//或者 d = d.getFullYear() + "-" + (d.getMonth()+1) + "-" + d.getDate();
06.
d = d.toLocaleDateString().replace(/[\u4e00-\u9fa5]/g,
'-'
).replace(/-$/,
''
)
07.
return
d;
08.
}
09.
alert(
"今天是:"
+showdate(0));
10.
alert(
"昨天是:"
+showdate(-1));
11.
alert(
"明天是:"
+showdate(1));
12.
alert(
"10天前是:"
+showdate(-10));
13.
alert(
"8天后是:"
+showdate(8));
1.
//将2005-8-5转换成2005-08-05格式
2.
var
strDate =
'2005-8-5'
;
3.
window.alert(strDate.replace(/\b(\w)\b/g,
'0$1'
));
01.
// 对Date的扩展,将 Date 转化为指定格式的String
02.
// 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符,
03.
// 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
04.
// 例子:
05.
// (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
06.
// (new Date()).Format("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18
07.
Date.prototype.Format =
function
(fmt) {
//@author: meizz
08.
var
o = {
09.
"M+"
:
this
.getMonth()+1,
//月份
10.
"d+"
:
this
.getDate(),
//日
11.
"h+"
:
this
.getHours(),
//小时
12.
"m+"
:
this
.getMinutes(),
//分
13.
"s+"
:
this
.getSeconds(),
//秒
14.
"q+"
: Math.floor((
this
.getMonth()+3)/3),
//季度
15.
"S"
:
this
.getMilliseconds()
//毫秒
16.
};
17.
if
(/(y+)/.test(fmt))
18.
fmt=fmt.replace(RegExp.$1, (
this
.getFullYear()+
""
).substr(4 - RegExp.$1.length));
19.
for
(
var
k
in
o)
20.
if
(
new
RegExp(
"("
+ k +
")"
).test(fmt))
21.
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : ((
"00"
+ o[k]).substr((
""
+ o[k]).length)));
22.
return
fmt;
23.
}
javascript日历可以写得很简单,也可以弄得很复杂。作为起步,我们先实现当前月的显示,然后再一点点改进。(其实我就不明白,分明是一个个月显示的,为什么不叫月历,而叫日历?!)
现在的问题怎样设置这些元素的内容,日历上面的空间并不都有数字的。首先我们得知道当前月第一天是星期几,因为js会把星期几转化为我们日历的第一行的数字;然后的问题是这个月有几天。我们先做个测试,把数组填空了再说!
01.
window.onload =
function
(){
02.
//*********************第一阶段,填空日期数组*******************
03.
var
now =
new
Date(),
04.
date = now.getDate(),
//当前天数
05.
month = now.getMonth() + 1,
//当前的月份
06.
year = now.getFullYear(),
//当前的年份
07.
firstday =
new
Date(now.getFullYear(), month -1 ,1).getDay(),
//求出当月的第一天是星期几
08.
lastday =
new
Date(now.getFullYear(), month , 0).getDate(),
//上月的第0天就是今月的最后一天
09.
dates = lastday,
//最后一天的号数就是这个月的天数
10.
arr =
new
Array(42);
//用来装载日期的数组,日期以‘xxxx-xx-xx’的形式表示
11.
for
(
var
i = 0,j = firstday; i < dates ; i ++ ,j ++){
12.
arr[j] = year +
'-'
+ month +
'-'
+ (i+1) ;
13.
}
14.
/***********************以下是测试部分**********************/
15.
for
(
var
i = 0;i <42;i++){
16.
document.write(arr[i]+
' '
);
//打印测试结果
17.
}
18.
}
接着下来我们就可以绘制UI了,我们用一个DIV来代表日历本身,头部由填满一行的span表示(也就是把span的display设为block),紧接着是星期数,它们都是a元素,下面是日期数,也是a元素。我们需要区分a元素的样式,让表示星期数的带上一个class来特别设置。样式我们暂时放弃动态生成。
01.
<!doctype html>
02.
<
html
dir
=
"ltr"
lang
=
"zh-CN"
>
03.
<
head
>
04.
<
meta
charset
=
"utf-8"
/>
05.
<
meta
http-equiv
=
"X-UA-Compatible"
content
=
"IE=Edge"
>
06.
<
title
>跨游览器的JS日历</
title
>
07.
<
style
type
=
"text/css"
>
08.
#jcalendar {
09.
width:210px;
10.
background:#E0ECF9;
11.
border:1px solid #479AC7;
12.
float:left;
13.
}
14.
#jcalendar span {
15.
float:left;
16.
width:210px;
17.
height:20px;
18.
background:#479AC7;
19.
color:#f90;
20.
font-weight:bolder;
21.
text-align:center;
22.
}
23.
#jcalendar .week {
24.
background:#D5F3F4;
25.
color:#808080;
26.
}
27.
#jcalendar .current{
28.
background:#336699;
29.
color:#fff;
30.
}
31.
#jcalendar a {
32.
display:block;
33.
float:left;
34.
width:30px;
35.
height:20px;
36.
color:#000;
37.
line-height:20px;
38.
text-align:center;
39.
text-decoration:none;
40.
}
41.
42.
</
style
>
43.
<
script
type
=
"text/javascript"
>
44.
</
script
>
45.
</
head
>
46.
<
body
>
47.
</
body
>
48.
</
html
>
01.
window.onload =
function
(){
02.
//*********************第一阶段,填空日期数组*******************
03.
//***************************略**************************
04.
//**********************第二阶段,绘制UI******************
05.
var
body = document.getElementsByTagName(
'body'
)[0],
//body的快捷引用
06.
a = document.createElement(
'a'
),
//日历的a元素,用于克隆
07.
calendar = document.createElement(
'div'
),
//日历的容器元素
08.
thead = document.createElement(
'span'
);
//日历的头部或页眉
09.
body.insertBefore(calendar,
null
);
//把日历加入DOM树中
10.
calendar.setAttribute(
'id'
,
'jcalendar'
);
11.
thead.innerHTML = year +
"年 "
+ month +
"月"
12.
calendar.appendChild(thead);
13.
var
weeks =
"日一二三四五六"
.split(
''
);
//日历第二行的内容,显示星期几
14.
for
(i = 0;i< 7;i++){
15.
var
th = a.cloneNode();
16.
th.innerHTML = weeks[i];
17.
th.className =
'week'
;
18.
calendar.appendChild(th);
19.
}
20.
for
(i = 0;i <42;i++){
21.
var
td = a.cloneNode();
22.
if
(arr[i] == undefined ){
23.
calendar.appendChild(td);
24.
}
else
{
25.
var
html = arr[i].split(
'-'
)[2];
26.
td.innerHTML = html;
27.
if
(html == date){
28.
td.className =
'current'
;
29.
}
30.
calendar.appendChild(td);
31.
}
32.
}
33.
}
好了,静态的日历就做出来了,现在我们加入动态元素,在头部添加四个按钮,让它选择上一月,下一月,上一年与下一年。由于我们的日历是基于那个填空数组,而填空数组是是基于年份与月份,因此年份与月份一改变,我们就不可避免地重绘整个日历。我们把重绘日历的逻辑独立出来做成一个函数,好让按钮上的函数去调用它!并在日期上添加悬浮效果与单击事件。
添加新样式
01.
#jcalendar .ybn {
02.
color
:
#000
;
03.
}
04.
#jcalendar .mbn {
05.
color
:
#000040
;
06.
}
07.
#jcalendar .weekend {
08.
color
:
#f00
!important
;
09.
}
10.
#jcalendar a.day:hover{
11.
background
:
#99C3F6
;
12.
}
javascript修改为:
01.
var
fillArray =
function
(year,month){
02.
var
firstday =
new
Date(year, month -1 ,1).getDay(),
//求出当月的第一天是星期几
03.
lastday =
new
Date(year, month , 0).getDate(),
//上个月的第零天就是今个月的最后一天
04.
dates = lastday,
//最后一天的号数就是这个月的天数
05.
arr =
new
Array(42);
//用来装载日期的数组,日期以‘xxxx-xx-xx’的形式表示
06.
for
(
var
i = 0,j = firstday; i < dates ; i ++ ,j ++){
07.
arr[j] = year +
'-'
+ month +
'-'
+ (i+1) ;
08.
}
09.
return
arr;
10.
}
11.
var
nextmonth =
function
(year,month,date){
//按钮事件1
12.
month = month + 1;
13.
if
(month > 12) year = year +1,month = 1;
14.
var
arr = fillArray(year,month);
15.
drawCalendar(arr,year,month,date);
16.
}
17.
var
nextyear =
function
(year,month,date){
//按钮事件2
18.
year = year + 1;
19.
var
arr = fillArray(year,month);
20.
drawCalendar(arr,year,month,date);
21.
}
22.
var
premonth =
function
(year,month,date){
//按钮事件3
23.
month = month - 1;
24.
if
(month < 1) year = year -1,month =12;
25.
var
arr = fillArray(year,month);
26.
drawCalendar(arr,year,month,date);
27.
}
28.
var
preyear =
function
(year,month,date){
//按钮事件4
29.
year = year - 1;
30.
var
arr = fillArray(year,month);
31.
drawCalendar(arr,year,month,date);
32.
}
33.
var
drawCalendar =
function
(arr,year,month,date){
34.
var
_calendar = document.getElementById(
"jcalendar"
);
35.
if
(_calendar) _calendar.parentNode.removeChild(_calendar);
36.
37.
var
body = document.getElementsByTagName(
'body'
)[0],
//body的快捷引用
38.
a = document.createElement(
'a'
),
//日历的a元素,用于克隆
39.
calendar = document.createElement(
'div'
),
//日历的容器元素
40.
thead = document.createElement(
'span'
);
//日历的头部或页眉
41.
body.insertBefore(calendar,
null
);
//把日历加入DOM树中
42.
calendar.setAttribute(
'id'
,
'jcalendar'
);
43.
var
args = year+
','
+month+
','
+date,
44.
preyear =
'<TT class=ybn onclick="preyear('
+args+
')"><<</TT>'
,
45.
premonth =
'<TT class=mbn onclick="premonth('
+args+
')"><</TT>'
,
46.
nextmonth =
'<TT class=mbn onclick="nextmonth('
+args+
')">></TT>'
,
47.
nextyear =
'<TT class=ybn onclick="nextyear('
+args+
')">>></TT>'
,
48.
str =
new
Date(args.replace(/,/g,
'/'
)).toLocaleDateString();
49.
thead.innerHTML = preyear +
' '
+premonth +
' '
+str+
' '
+nextmonth +
' '
+nextyear;
50.
calendar.appendChild(thead);
51.
var
weeks =
"日一二三四五六"
.split(
''
);
//日历第二行的内容,显示星期几
52.
for
(i = 0;i< 7;i++){
53.
var
th = a.cloneNode();
54.
th.innerHTML = weeks[i];
55.
th.className =
'week'
;
56.
calendar.appendChild(th);
57.
}
58.
for
(i = 0;i <42;i++){
59.
var
td = a.cloneNode();
60.
if
(arr[i] == undefined ){
61.
calendar.appendChild(td);
62.
}
else
{
63.
var
html = arr[i].split(
'-'
)[2];
64.
td.innerHTML = html;
65.
td.className =
'day'
;
66.
td.href =
"javascript:void(0)"
;
//为ie6准备的
67.
if
(date && html == date){
68.
td.className = td.className +
' current'
;
69.
}
70.
if
(i%7 == 0 || i%7 == 6){
71.
td.className = td.className +
' weekend'
;
72.
}
73.
td.onclick = (
function
(i){
74.
return
function
(){
75.
alert(i);
//这里后面我们要修改,让arr[i]填空文本域
76.
}
77.
})(arr[i]);
78.
calendar.appendChild(td);
79.
}
80.
}
81.
}
82.
window.onload =
function
(){
83.
//*********************第一阶段,填空日期数组*******************
84.
var
now =
new
Date(),
85.
month = now.getMonth() + 1,
//当前的月份
86.
year = now.getFullYear(),
//当前的年份
87.
date = now.getDate(),
88.
arr = fillArray(year,month);
89.
//**********************第二阶段,绘制UI******************
90.
drawCalendar(arr,year,month,date);
91.
}
好了,该有的都有了,现在封装一下它吧。把上面四个按钮事件合并成一个,加个更见名达义的名称,然后统统塞到一个类中。
001.
var
Class = {
002.
create:
function
() {
003.
return
function
() {
004.
this
.initialize.apply(
this
, arguments);
005.
}
006.
}
007.
}
008.
//*********************Jcalendar类开始**********************
009.
var
Jcalendar = Class.create();
010.
Jcalendar.prototype = {
011.
initialize:
function
(){
012.
var
$ =
new
Date();
013.
this
.drawCalendar($.getFullYear(),$.getMonth() + 1,$.getDate());
014.
},
015.
fillArray :
function
(year,month){
016.
var
f =
new
Date(year, month -1 ,1).getDay(),
//求出当月的第一天是星期几
017.
dates =
new
Date(year, month , 0).getDate(),
//上个月的第零天就是今个月的最后一天
018.
arr =
new
Array(42);
//用来装载日期的数组,日期以‘xxxx-xx-xx’的形式表示
019.
for
(
var
i = 0; i < dates ; i ++ ,f ++){
020.
arr[f] = year +
'-'
+ month +
'-'
+ (i+1) ;
021.
}
022.
return
arr;
023.
},
024.
drawCalendar :
function
(year,month,date){
025.
var
$ = document,$$ =
'createElement'
,
026.
_calendar = $.getElementById(
"jcalendar"
);
027.
if
(_calendar) _calendar.parentNode.removeChild(_calendar);
//推倒重绘!
028.
var
body = $.getElementsByTagName(
'body'
)[0],
//body的快捷引用
029.
weeks =
"日一二三四五六"
.split(
''
),
//日历第二行的内容,显示星期几
030.
calendar = $[$$](
'div'
),
//日历的容器元素
031.
a = $[$$](
'a'
),
//日历的a元素,用于克隆
032.
tt = $[$$](
"tt"
),
//日历页眉的tt元素,用于克隆
033.
thead = $[$$](
'span'
),
//日历页眉
034.
fragment = $.createDocumentFragment(),
//减少DOM刷新页面的次数
035.
arr =
this
.fillArray(year,month),
//保存当月的日期
036.
tts = [],
//用于保存tt元素的引用
037.
ths =
this
;
//用于保存Jcalendar对象的实例的引用
038.
body.insertBefore(calendar,
null
);
//把日历加入DOM树中
039.
calendar.setAttribute(
'id'
,
'jcalendar'
);
040.
for
(
var
i = 0;i<4;i++){
//循环生成出个时间按钮。
041.
var
clone = tt.cloneNode(
true
);
//比重新createElement快
042.
clone.onclick = (
function
(index){
043.
return
function
(){
//在闭包里绑定事件
044.
ths.redrawCalendar(year,month,date,index)
045.
}
046.
})(i);
047.
tts[i] = clone;
//保存引用
048.
if
(i==2) thead.appendChild($.createTextNode(year+
"年"
+month+
"月"
+date+
"日"
));
049.
thead.appendChild(clone);
050.
}
051.
tts[0].innerHTML =
'<<'
;
052.
tts[1].innerHTML =
'<'
;
053.
tts[2].innerHTML =
'>'
;
054.
tts[3].innerHTML =
'>>'
;
055.
tts[0].className = tts[3].className =
'mbn'
;
056.
tts[1].className = tts[2].className =
'ybn'
;
057.
fragment.appendChild(thead);
058.
for
(i = 0;i <7;i++){
//星期显示区
059.
var
th = a.cloneNode(
true
);
060.
th.innerHTML = weeks[i];
061.
th.className =
'week'
;
062.
fragment.appendChild(th);
063.
}
064.
for
(i = 0;i <42;i++){
//日期显示区
065.
var
td = a.cloneNode(
true
);
066.
if
(arr[i] == undefined ){
067.
fragment.appendChild(td);
068.
}
else
{
069.
var
html = arr[i].split(
'-'
)[2];
070.
td.innerHTML = html;
071.
td.className =
'day'
;
072.
td.href =
"javascript:void(0)"
;
//为ie6准备的
073.
(date && html == date)&&(td.className +=
' current'
) ;
//高亮每个月今天这一天
074.
(i%7 == 0 || i%7 == 6)&&(td.className +=
' weekend'
) ;
//为周末添加多一个类
075.
td.onclick = (
function
(i){
076.
return
function
(){
077.
alert(i);
078.
}
079.
})(arr[i]);
080.
fragment.appendChild(td);
081.
}
082.
}
083.
calendar.appendChild(fragment);
084.
},
085.
086.
redrawCalendar :
function
(year,month,date,index){
087.
switch
(index){
088.
case
0 :
//preyear
089.
year--;
090.
break
;
091.
case
1:
//premonth
092.
month--;
093.
(month < 1) &&(year--,month = 12) ;
094.
break
;
095.
case
2:
//nextmonth
096.
month++;
097.
(month > 12)&&(year++,month = 1) ;
098.
break
;
099.
case
3:
//nextyear
100.
year++;
101.
break
;
102.
}
103.
this
.drawCalendar(year,month,date);
104.
}
105.
}
106.
//*********************Jcalendar类结束**********************
107.
window.onload =
function
(){
108.
new
Jcalendar();
109.
}
上面的按钮的显示符号应该是<与>,而不是单纯的小于号或大于号,这是高亮插件的缘故……另,这个日历改一改,就可以成为弹出式日期选择器了!至于它,下次有次再说!