Index

HOME > プログラムTOP > JavaScript



万年カレンダー

 JavaScript製万年カレンダーのサンプルです。ここでは、単純な万年カレンダーのつくり方を紹介しています。このカレンダーは、HTMLページを更新しなくても、カレンダーの部分だけが更新表示されるようにしています。対象ブラウザは、IE5以上、NN6以上、Safari、Firefox などのDOM対応ブラウザです。
 ・関連ページ  ・「日時を表示する」 (日時表示の基礎知識)
 ・「単月カレンダー」 (カレンダー入門篇)
 ・「単月カレンダー(休日付)」 (カレンダー初級篇)
 ・「万年カレンダー」 (カレンダー中級篇)
 ・「万年カレンダー(休日付)」 (カレンダー上級篇)
  

sasaraan programming

Exposition

■変数の宣言と初期化

 ここでは、カレンダーの作成を関数にしています。作成する関数の種類は以下の通りです。
関数名機能
・InitCalendar(parent_id)... カレンダーの初期化 : SetCalendar関数を呼び出す
・SetCalender(year,month)... カレンダーの作成 : テーブルの作成
・SetPrevMonth()... 前月の表示 : SetCalendar関数を呼び出す
・SetNextMonth()... 翌月の表示 : SetCalendar関数を呼び出す
 最初に "InitCalendar" 関数を呼び出せば、当月のカレンダーが表示されます。この時、引数に親オブジェクト(要素)の id 文字列を渡す必要があります。
<div id="cal"></div>
<script type="text/javascript"><!--
    InitCalendar("cal");
//--></script>
 以下はグローバル変数と初期化関数です。aDaysは各月の日数、aWeekは曜日を表示する際の文字列の配列です。また、objParentは親オブジェクト(通常はdiv要素)、tCalendarはカレンダーオブジェクト(= table要素)を示します。現在表示中の年月を記憶しておく必要があるため、nYear, nMonth を設定しています。
var aDays = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);  // 各月の日数
var aWeek = new Array("日", "月", "火", "水", "木", "金", "土");    // 曜日の文字列
var objParent;     // 親オブジェクト
var tCalendar;     // カレンダーオブジェクト
var nYear;         // 表示年
var nMonth;       // 表示月

// カレンダーの初期化
// 引数 : parent_id(親オブジェクトの id文字列)
function InitCalendar(parent_id) {
    if (document.getElementById) {
        objParent = document.getElementById(parent_id);
        SetCalendar(0, 0);
    }
}    
 なお、カレンダーの作成には、以下に示す DOM(Document Object Model)のメソッドを利用しています。
メソッド機能
document.getElementById(str)... id属性値(str)から要素を取得する
doccument.createElement(str)... 要素名strの要素を作成する
document.createTextNode(str)... 文字列strを作成する
object.appendChild(obj)... objectに子要素objを追加する
object.removeChild(obj)... objectから子要素objを削除する

■カレンダーの作成

 カレンダーの作成は SetCalendar関数で行います。DOMを使用していますが、基本的に、単月カレンダーと同じプロセスとなります。違いは、月初の曜日を取得する際、年と月を指定する必要がある(単月の時は日にちのみ)のと、前月と翌月へのリンクの作成が追加されていることです。
// カレンダーの描画
// 引数 : year(表示年), month(表示月) : 0で現在の年月を表示
function SetCalendar(year, month) {
    if (!objParent) return;
    var nDate = new Date();    // Date オブジェクト
    var nDays;        // 表示月の日数 : 28 - 31
    var nFirstDay;    // 月初の曜日 : 0(Sun.) - 6(Sat.)
    var i, j;    

    nYear = (!year)? nDate.getFullYear(): year;        // 表示年
    nMonth = (!month)? (nDate.getMonth() + 1): month;  // 表示月
		
    // ひと月の日数
    nDays = aDays[nMonth-1];
    if (nMonth == 2) {        /* うるう年のチェック */
        if (nYear % 400 == 0) nDays =29;
        else if (nYear % 100 == 0) nDays = 28;
        else if (nYear % 4 == 0) nDays= 29;
    }

    // 年月の描画
    tCalendar = document.createElement("table");
    with (tCalendar) {
        style.width = "160px";
        style.margin = "0";
        style.tableLayout = "fixed";
        style.border = "1px solid #999999";
        style.backgroundColor = "#f5ffea";
        style.fontSize = "12px";
        style.lineHeight = "16px";
    }
    var tbCalendar = document.createElement("tbody");

    // 見出し行(年月の表示)
    var trCaption = document.createElement("tr");
    var tdCaption = document.createElement("td");
    var strCaption = document.createTextNode(nYear + "年 " + nMonth + "月")
    with (tdCaption) {
        colSpan = "7";
        style.padding = "0px";
        style.borderBottom = "1px solid #cccccc";
        style.textAlign = "center";
    }
    trCaption.appendChild(tdCaption);  // 見出しセル
    tdCaption.appendChild(strCaption); // 年・月の文字列

    // 月移動ボタン(リンク)
    var lnkPrev = document.createElement("a");
    var lnkNext = document.createElement("a");
    lnkPrev.style.marginLeft = "10px";
    lnkNext.style.marginLeft = "10px";
    lnkPrev.style.color = "green";
    lnkNext.style.color = "green";
    lnkPrev.href = "javascript:SetPrevMonth()";
    lnkNext.href = "javascript:SetNextMonth()";
    lnkPrev.appendChild(document.createTextNode("前月"));
    lnkNext.appendChild(document.createTextNode("翌月"));
    tdCaption.appendChild(lnkPrev);
    tdCaption.appendChild(lnkNext);

    tbCalendar.appendChild(trCaption); // 見出し行

    // 曜日行 : "日、月、・・・土" の各文字列をセット
    var trWeek = document.createElement("tr");
    for (i = 0; i<7; i++) {
        var tdWeek = document.createElement("td");
        with (tdWeek) {
            style.padding = "0";
            style.textAlign = "center";
            appendChild(document.createTextNode(aWeek[i]));
        }
        trWeek.appendChild(tdWeek);
    }
    tbCalendar.appendChild(trWeek);  // 曜日行

    // 月初の曜日を取得
    nDate.setFullYear(nYear);
    nDate.setMonth(nMonth-1);
    nDate.setDate(1);
    nFirstDay = nDate.getDay();

    // 日にち行 : 月末まで表示
    var row = document.createElement("tr");
    var cell = new Array(nDays);
    for (i=-nFirstDay, j=0; i<nDays; i++) {
        cell[i] = document.createElement("td");
        with (cell[i]) {
            style.padding = 0;
            style.textAlign = "center";
            if (i < 0) {
                appendChild(document.createTextNode(""));  // 一日まで空白で埋める
            } else {
                appendChild(document.createTextNode(i+1));  // 日付
            }			
            row.appendChild(cell[i]);
        }
        if (++j == 7 && i != nDays-1) {     /* 月末でない土曜の時は改行 */
            tbCalendar.appendChild(row);
            row = document.createElement("tr");
            j = 0;
        } 
    }
    tbCalendar.appendChild(row);

    //テーブルの表示
    tCalendar.appendChild(tbCalendar);
    objParent.appendChild(tCalendar);
}    
 上記サンプルでは、スタイル(CSS)の設定もコードで行っているので、関数がだいぶ長くなっています。適宜別関数にしたり、CSSを別に記述するなどすればスリムになります。

■月の移動

// 前月の表示
function SetPrevMonth() {
    if (nMonth == 1) {     /* 今の表示月が1月の時は年も調整 */
        nMonth = 12;
        nYear--;
    } else {
        nMonth--;
    }
    if (tCalendar) objParent.removeChild(tCalendar); // テーブルオブジェクトの破棄
    SetCalendar(nYear, nMonth);          // テーブルオブジェクトの生成
}

// 翌月の表示
function SetNextMonth() {
    if (nMonth == 12) {     /* 今の表示月が12月の時は年も調整 */
        nMonth = 1;
        nYear++;
    } else {
        nMonth++;
    }
    if (tCalendar) objParent.removeChild(tCalendar); // テーブルオブジェクトの破棄
    SetCalendar(nYear, nMonth);          // テーブルオブジェクトの生成	
}    
 前月または翌月に月を移動させる際は、一旦今のテーブルオブジェクトを破棄してから再度カレンダーを作成します。前月への移動で現在の表示が1月の時、翌月への移動で現在の表示月が12月の時は、年も増減する必要があります。

www.sasaraan.net

(c) morijoh