Web頁中的日歷一般離不開表格,通常都使用表格裝載指定月的日期等信息。所以,要編寫JS日歷,首先必須解決的問題是表格的行與列問題。列是固定的,七列,因為一周有七天。行需要動態計算,因為,每一個月的第一天是星期幾是一個變數,因而第一天在表格中的第幾個單元也就跟着變化,同時,每個月的總天數不一致也影響着各個月對表格行數的需要量。
一. 表格的行數問題
1.首先取得處理月的總天數
JS不提供此參數,我們需要計算。考慮到閏年問題會影響二月份的天數,我們先編寫一個判斷閏年的自編函數:
//判斷是否為閏年 function is_leap(year) { //閏年的條件是符合下面二者之一: //(1)年份能被4整除,但不能被100整除; //(2)年份能被400整除。 if((year%4==0 && year%100!=0)||(year%400==0)){ return 1; } return 0; }
接着定義一個包含十二個月在內的月份總天數的數組:
days_of_month = new Array(31, 28+is_leap(fullYear), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
days_of_month這個數組里,二月份的天數已經加入閏年的信息:28+is_leap(year)。數組元素從0開始,正好對應於JS提供的Date函數提供的getMonth返回值,即0表示一月,1表示二月,2表示三月,依此類推。
這樣,各月總數可以這樣取得:days_of_month[x]。其中,x為0至11的自然數。
2.計算處理月第一天是星期幾
可以使用Date函數的getDay取得,返回的值從0到6,0表示星期一,1表示星期二,2表示星期三,其余依此類推。代碼如下(假設要處理的時間為2008年3月):
date=new Date(2008, 3, 1); week=date.getDay();
有了月總天數和該月第一天是星期幾這兩個已知條件,就可以解決表格所需行數問題:(當前月天數+第一天是星期幾的數值)除以七。表格函數需要整數,因此,我們使用Math.ceil來處理:
rows=Math.ceil((days_of_month[month] + week) / 7);
表格中的tr標簽實際上代表表格的行,因此變量tr_str是我們往下寫表格的重要依據。
二. 打印日歷表格
可以使用兩個for語句嵌套起來實現:外層for語句寫行,內層for語句寫單元格。
for(i=0;i<rows;i++) { //外層for語句 - tr標簽 document.write("<tr>"); for(k=0;k<7;k++) { //內層for語句 - td標簽 idx=i*7+k; //表格單元的自然序號 date_str=idx-firstday+1; //計算日期 //這里是處理有效日期代碼 } //內層for語句結束 document.write("</tr>"); } //外層for語句結束
單元格的自然序號是否代表有效日期非常關鍵,為此必須加入一個過濾機制:僅打印有效的日期。有效的日期大於0小於小於等於處理月的總天數。
三. 以下是完整的JS日歷代碼
<%@ page language="java" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); %> <!DOCTYPE html> <html lang="zh-cn"> <head> <title>自定義日歷</title> <meta content="IE=edge" http-equiv="X-UA-Compatible"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta http-equiv="Content-Language" content="zh-cn" /> <meta name="author" content="linjiqin218@126.com" /> <meta name="Copyright" content="parami|廈門波羅密網絡科技有限公司" /> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <script language="javascript"> //判斷是否為閏年 function is_leap(year) { //閏年的條件是符合下面二者之一: //(1)年份能被4整除,但不能被100整除; //(2)年份能被400整除。 if((year%4==0 && year%100!=0)||(year%400==0)){ return 1; } return 0; } //var date = new Date(2013, 1, 4); //特定Date資訊 var date = new Date(); //當前Date資訊 var fullYear = date.getFullYear(); //獲取年份 var month = date.getMonth(); //獲取月份,返回值是0(一月)到11(十二月)之間的一個整數。 var date_of_month = date.getDate(); //獲取日期,返回值是1~31之間的一個整數 var first_date = new Date(fullYear, month, 1); //獲取當前月第一天Date資訊 //返回date對象星期中的一天,此值為0(周日)-6(周六)之間的一個整數 var week = first_date.getDay(); //獲取當前月第一天是星期幾 var days_of_month = new Array(31, 28+is_leap(fullYear), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); //各月份的總天數 var rows = Math.ceil((days_of_month[month] + week) / 7); //表格所需要行數 var table='<table id="table" width="708px;" cellpadding="5" cellspacing="1">'; table+="<tr bgcolor='#DEE9F4'>"; table+="<td align='center'>日</td>"; table+="<td align='center'>一</td>"; table+="<td align='center'>二</td>"; table+="<td align='center'>三</td>"; table+="<td align='center'>四</td>"; table+="<td align='center'>五</td>"; table+="<td align='center'>六</td>"; table+="</tr>"; //打印表格第一行(有星期標志) for (i = 0; i < rows; i++) { //表格的行 table += "<tr bgcolor='#DEE9F4'>"; for (k = 0; k < 7; k++) { //表格每行的單元格 idx = i * 7 + k; //單元格自然序列號 date_str = idx - week + 1; //計算日期 //過濾無效日期(小於等於零的、大於月總天數的) (date_str <= 0 || date_str > days_of_month[month]) ? date_str = " " : date_str = idx - week + 1; //打印日期:今天底色為紅 if (date_str == date_of_month) { table += "<td align='center' bgcolor='red'>" + date_str + "</td>" } else { table += "<td align='center'>" + date_str + "</td>"; } } table += "</tr>"; //表格的行結束 } table += "</table>"; //表格結束 document.write(table); </script> </head> <body> </body> </html>
四. 效果如下圖所示
如果,您認為閱讀這篇博客讓您有些收獲,不妨點擊一下右下角的【推薦】。
如果,您希望更容易地發現我的新博客,不妨點擊一下左下角的【關注我】。
如果,您對我的博客所講述的內容有興趣,請繼續關注我的后續博客,我是【Ruthless】。
本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。