练习一个日历例子,输出一个日历,显示当前日期为红色
主要的理解和掌握点是:
使用Date()函数
根据天数计算日历的长度,主要是行,因为列是固定的,一周只有7天
根据天数计算各天放置的单元格位置
每月第一天的特殊处理
很多时候是从索引0开始计算,例如0-11代表12个月之类
一个包括12个月的天数的数组
效果图:
日 一 二 三 四 五 六
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
代码:
function is_leap(year) {
return (year % 100 == 0 ? res = (year % 400 == 0 ? 1 : 0) : res = (year % 4 == 0 ? 1 : 0));
} //是否为闰年
var nstr = new Date(); //当前Date资讯
var ynow = nstr.getFullYear(); //年份
var mnow = nstr.getMonth(); //月份
var dnow = nstr.getDate(); //今日日期
var n1str = new Date(ynow, mnow, 1); //传入获取到的年月,并且日设置为1,获取当月的第一天的日期信息
var firstday = n1str.getDay(); //当月第一天星期几
var m_days = new Array(31, 28 + is_leap(ynow), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); //各月份的总天数
//月份天数+第一天星期几 除以7,获取整数行数,然后取整,得到表格所需要行数,即这个月的天数需要排多少行
var tr_str = Math.ceil((m_days[mnow] + firstday) / 7);
//打印表格第一行(有星期标志)(表头)
document.write("<table border='1' align='center' width='220' cellspacing='0'><tr><td align='center'>日</td><td align='center'>一</td><td align='center'>二</td><td align='center'>三</td><td align='center'>四</td><td align='center'>五</td><td align='center'>六</td></tr>");
//举例是2016年12月,有31天
for (var i = 0; i < tr_str; i++) { //表格的行,根据当前月份的天数来确定这个月要排多少行
document.write("<tr>");//表格的行开始
for (var k = 0; k < 7; k++) { //表格每行的单元格,每行只有7格,0-6
//单元格自然序列号,当前行号乘以7再加上当前行的空格号
idx = i * 7 + k; //例如第一行的第一格就是0x7+0 =0
date_str = idx - firstday + 1; //计算日期,例如第一行第一格就是0-当月的第一天(目前当月第一天是周四即4)+1,等于-3是一个负数,负数会显示空格(参看下面)
//控制日期的值在不同的星期里面显示,如果20号是周一的话,那么就要放在周一的列里面,如此类推
(date_str <= 0 || date_str > m_days[mnow]) //过滤无效日期(小于等于零的、大于月总天数的)
? date_str = " " //显示空格
: date_str = idx - firstday + 1;
//打印日期:今天底色为红
date_str == dnow
? document.write("<td align='center' bgcolor='red'>" + date_str + "</td>")
: document.write("<td align='center'>" + date_str + "</td>");
}
document.write("</tr>"); //表格的行结束
}
document.write("</table>"); //表格结束
这里有几个重点:
Math.ceil((m_days[mnow] + firstday) / 7)
A: 将当月的日数和1号左边的空白格相加是因为第一天可能会排在其他空格里面,所以要把第一天左边的空格的数量也加上,
这样才符合日历的设计,除以7是因为一个星期只有7天,然后进行取整,例如将4.5行取整为5行
idx = i * 7 + k;
A: 这是作为日历的每一个格的编号用的,因为如果不这样使用的话,没办法将第一行输出0-6,
然后第二行输出7-13,然后第三行14-20......所以这里需要用 i*7 +k 来实现这个格式
date_str = idx - firstday + 1;
A: firstday是获取当月的第一天的周几,用日历的每一个格的编号来减去 firstday 的话,可以确定每一个格的日期,
日 一 二 三 四 五 六
-4 -3 -2 -1 0 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
但是考虑到没有0的开始日期,所以需要额外加一
所以,(date_str <= 0 || date_str > m_days[mnow])
这个判断就是为了过滤负数和超过31的日期
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。