JavaScriptでカレンダー

注:参考サイト様のサンプルを自分が後で見たときにわかるように言葉を変えて丸写ししただけです。

カレンダーの基本的な形

<script>
//head内記載分
var myDate = new Date();
var myWeekTbl = new Array("日","月","火","水","木","金","土");
var myMonthTbl = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
if (((myYear%4)==0 && (myYear%100)!=0) || (myYear%400)==0){
    myMonthTbl[1] = 29;
}
 
var myYear = myDate.getFullYear();//2013
var myMonth = myDate.getMonth();//月(0~11)
var myToday = myDate.getDate();//何日
var myWeek = myDate.getDay();//曜日(0~6)いらない行
 
myDate.setDate(1); //今月1日の情報を取得できる。ここでは曜日
var myWeek = myDate.getDay();//12月は0=日曜日
var myTblLine = Math.ceil((myWeek+myMonthTbl[myMonth])/7);//0と31日を足すとカレンダーテーブルの総マス数これを7で割って切り上げると行数
var myTable = new Array(7*myTblLine);//マス目全ての配列を作る
 
for(i=0; i<7*myTblLine; i++){
    myTable[i]="-";    //適当に値を入れる
}
for(i=0; i<myMonthTbl[myMonth]; i++){
    myTable[myWeek+i] =i+1;    //適当な空欄に日にちを入れる
}
</script>

date関数で、今日の年月日曜日を取得して、変数myDateに入れる。Dateコンストラクタを使用する。

newでArrayコンストラクタを、各曜日を引数にして生成する。newを付けず、var myWeekTbl=["日","月","火","水","木","金","土"];のようにしても同じ。

同様にして各月ごとの日数を配列に格納。

問題となるのはうるう年で、うるう年の基準である「西暦(2014年等)を4で割り切れる(でも100で割り切れる年を除く)or西暦を400で割り切れる年」であれば、2月の日数は29日とする。

そうしたら、変数myDateに格納した日付情報を、getFullYear()にて年を、getMonth()にて月(0~11)を、getDate()で日にちを、getDay()にて曜日(0~6)を取り出して、各変数に格納する。

次に今月1日の情報を取得するために、myDate変数に対して、setDate(1)としてメソッドを実行する。これにgetDay()することにより今月1日の曜日を知ることができ、同時に今月カレンダーの開始位置を知ることができる。

テーブルの行数を取得するために、1日の開始マスの数にその月の総日数を足して、それを7で割ってceilで切り上げて行数を求めているが、面倒なら6行固定にしてmyTblLineを6として扱えばよいと思われる。で、全マス目の分だけ配列を作っている。

そしたらfor文で全てのマスに適当な値を入れて、そのあと、1日目が始まるマスから(myWeek+0番目から)、その月の総日数分だけ日にちで上書きする。

<script>
//body内記載分
document.write("<table border='1'>");
for(i=0; i<myTblLine; i++){
    document.write("<tr>");
    for(j=0; j<7; j++){
        document.write("<td>");
        myDat = myTable[j+(i*7)];//ポイント→日にちの計算方法
        document.write(myDat);
        document.write("</td>");
    }
    document.write("</tr>");
}
document.write("</table>");
</script>

body内ではdocument.write()を使ってテーブルを生成する。

for文を行の分と列の分で合わせて2つ用意して、列のfor文では、マス目配列myTableから順番に値を取り出して入れていく。この際、1列また1行ずつiやjはリセットされていくため、iに7を掛けることを忘れずに。それをdata変数に格納して表示させる。

カレンダーを装飾する

カレンダーを装飾するためにbody内をいじくります。

//body内記載分
document.write("<table class='d1'>");
 
document.write("<tr class='d2'><td colspan='7'>"+myYear+"年"+(myMonth+1)+"月</td></tr>");
document.write("<tr class='d6'>");
for(i=0; i<7; i++){
if(i==0){
document.write("<td class='d3a'");
}else if(i==6){
document.write("<td class='d4a'");
}else{
document.write("<td");
}
document.write(">"+myWeekTbl[i]+"</td>");
}
document.write("</tr>");
 
for(i=0; i<myTblLine; i++){
    document.write("<tr>");
    for(j=0; j<7; j++){
        var myDat = myTable[j+(i*7)];//ポイント→日にちの計算方法。myTableの値を1つずつ取り出す。
if(myDat==myToday){//今日
    document.write("<td class='d5'>");
}else if(j==0){//日曜日
    document.write("<td class='d3'>");
}else if(j==6){//土曜日
    document.write("<td class='d4'>");
}else if((myMonth==0)&&(myDat==1)||//2014.1.1.元旦
    (myMonth==0)&&(myDat==13)||//2014.1.13.成人の日
    (myMonth==1)&&(myDat==11)||//2014.2.11.建国記念の日
    (myMonth==2)&&(myDat==21)||//2014.3.21.春分の日
    (myMonth==3)&&(myDat==29)||//2014.4.29.昭和の日
    (myMonth==4)&&(myDat==3)||//2014.5.3.憲法記念日
    (myMonth==4)&&(myDat==4)||//2014.5.4.みどりの日
    (myMonth==4)&&(myDat==5)||//2014.5.5.こどもの日
    (myMonth==4)&&(myDat==6)||//2014.5.6.振替休日
    (myMonth==6)&&(myDat==21)||//2014.7.21.海の日
    (myMonth==8)&&(myDat==15)||//2014.9.15.敬老の日
    (myMonth==8)&&(myDat==23)||//2014.9.23.秋分の日
    (myMonth==9)&&(myDat==13)||//2014.10.13.体育の日
    (myMonth==10)&&(myDat==3)||//2014.11.3.文化の日
    (myMonth==10)&&(myDat==23)||//2014.11.23.勤労感謝の日
    (myMonth==10)&&(myDat==24)||//2014.11.24.振替休日
    (myMonth==11)&&(myDat==23)){ //2014.12.23.天皇誕生日
    document.write("<td class='d3'>");
 
}else{
    document.write("<td>");
}
    document.write(myDat);
    document.write("</td>");
    }
    document.write("</tr>");
    }
document.write("</table>");

tableやtdに対してクラスを指定して装飾を施します。また、該当の日付の場合に色を付ける操作を指定ます。

問題は祝日で、振替休日がいつになるとか、春分と秋分が毎年変わったりと、プログラムで自動的に変えるのは難しいのでここ何年くらいであれば手書きでもいいのではと思ってしまいます。てかそれしかできません。。。

/* css内の記述 */
.d1 {
	border-collapse:collapse;
	text-align:center;
	margin:0 0 0 25px;
	width:250px;
	}
.d1 td {
	border:solid 1px #ccc;
	height:22px;
	}
.d2 td {
	font-weight:bold;
	font-size:18px;
	color:#0395e1;
	border:none;
	}
.d3,.d3a {
	color:#f00;
	}
.d3 {
	background:#fee;
	}
.d4,.d4a {
	color:#00f;
	}
.d4 {
	background:#eef;
	}
.d5 {
	background:#ff8;
	font-weight:bold;
	}
.d6 {
	font-weight:bold;
	background:#efe;
	}

カレンダーをカスタマイズ

今月分のカレンダーだけであればこれでいいんですが、先月とか翌月のカレンダーを表示させるのにはどうすればよいかという話。

function abc(myTodayOffset){
var myDate = new Date();
var myWeekTbl = new Array("日","月","火","水","木","金","土");
var myMonthTbl = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
 
var myMonth = myDate.getMonth();//月
var myToday = myDate.getDate();//何日(今日の日にち)
var myWeek = myDate.getDay();//曜日(0~
 
myDate.setDate(1); //今月1日の情報を取得できる。
myMonth = myMonth+myTodayOffset;//前月、翌月データ補正
myDate.setMonth(myMonth);
myYear = myDate.getFullYear();//年を再取得
myMonth = myDate.getMonth();//月を再取得
myWeek = myDate.getDay();//曜日を再取得
if (((myYear%4)==0 && (myYear%100)!=0) || (myYear%400)==0){
    myMonthTbl[1] = 29;
}
 
var myTable = new Array(7*6);//マス目全ての配列を作る
 
for(i=0; i<42; i++){
    myTable[i]=" ";    //適当に値を入れる
}
for(i=0; i<myMonthTbl[myMonth]; i++){
    myTable[myWeek+i] =i+1;    //適当な空欄に日にちを入れる
}
 
document.write("<div class='d8'><table class='d1'>");
 
document.write("<tr class='d2'><td colspan='7'>"+myYear+"年"+(myMonth+1)+"月</td></tr>");
document.write("<tr class='d6'>");
for(i=0; i<7; i++){
if(i==0){
document.write("<td class='d3a'");
}else if(i==6){
document.write("<td class='d4a'");
}else{
document.write("<td");
}
document.write(">"+myWeekTbl[i]+"</td>");
}
document.write("</tr>");
 
for(i=0; i<6; i++){
    document.write("<tr>");
    for(j=0; j<7; j++){
        var myDat = myTable[j+(i*7)];//ポイント→日にちの計算方法。myTableの値を1つずつ取り出す。
if((myDat==myToday)&&(myTodayOffset==0)){//今日
    document.write("<td class='d5'>");
}else if(j==0){//日曜日
    document.write("<td class='d3'>");
}else if(j==6){//土曜日
    document.write("<td class='d4'>");
}else if(myYear==2013){
    if((myMonth==11)&&(myDat==23)||(myMonth==10)&&(myDat==4)||(myMonth==10)&&(myDat==23)){ //2013.12.23 天皇誕生日
    document.write("<td class='d3'>");
    }else{
    document.write("<td>");
    }
}else if(myYear==2014){
    if((myMonth==0)&&(myDat==1)||//2014.1.1.元旦
    (myMonth==0)&&(myDat==13)||//2014.1.13.成人の日
    (myMonth==1)&&(myDat==11)||//2014.2.11.建国記念の日
    (myMonth==2)&&(myDat==21)||//2014.3.21.春分の日
    (myMonth==3)&&(myDat==29)||//2014.4.29.昭和の日
    (myMonth==4)&&(myDat==3)||//2014.5.3.憲法記念日
    (myMonth==4)&&(myDat==4)||//2014.5.4.みどりの日
    (myMonth==4)&&(myDat==5)||//2014.5.5.こどもの日
    (myMonth==4)&&(myDat==6)||//2014.5.6.振替休日
    (myMonth==6)&&(myDat==21)||//2014.7.21.海の日
    (myMonth==8)&&(myDat==15)||//2014.9.15.敬老の日
    (myMonth==8)&&(myDat==23)||//2014.9.23.秋分の日
    (myMonth==9)&&(myDat==13)||//2014.10.13.体育の日
    (myMonth==10)&&(myDat==3)||//2014.11.3.文化の日
    (myMonth==10)&&(myDat==23)||//2014.11.23.勤労感謝の日
    (myMonth==10)&&(myDat==24)||//2014.11.24.振替休日
    (myMonth==11)&&(myDat==23)){ //2014.12.23.天皇誕生日
    document.write("<td class='d3'>");
    }else{
    document.write("<td>");
    }
}else{
    document.write("<td>");
}
    document.write(myDat);
    document.write("</td>");
    }
    document.write("</tr>");
    }
document.write("</table></div>");
}

上記を一つの関数として関数宣言して、引数にmyTodayOffsetという0なら今月、1なら翌月、-1なら先月を選択できるパラメータを追加する。

そしたら、下のようなHTMLを記述する。

<div id="d11">
<div id="d12"><img src="hidari.gif" alt="" /></div><div id="d13"><img src="migi.gif" alt="" /></div>
<div id="d10">
<div id="d9" class="clearfix">
<script>
abc(-1);
abc(0);
abc(1);
abc(2);
abc(3);
</script>
</div></div></div>

divで囲んでいるのは、下のようにjQueryを使用してアニメーションさせたいからで、アニメーションさせるまえにfloatで横並びにして、当月以外はoverflow:hiddenで隠しておく。

.d7 td {
	font-size:13px;
	color:#666;
	padding:5px 0 0 10px;
	text-align:left;
	border:none;
	}

div.d8 {
	width:300px;
	float:left;
	}
div#d9 {
	width:1500px;
	height:100%;
	}
div#d10{
	width:100%;
	height:100%;
	overflow:hidden;
	}
div#d11{
	width:300px;
	height:auto;
	position:relative;
	}
div#d12 {
	position:absolute;
	top:2px;
	left:50px;
	cursor:pointer;
	}
div#d13 {
	position:absolute;
	top:2px;
	left:225px;
	cursor:pointer;
	}

スタイルが適用できたら、jQueryでスライドさせるだけ。parseIntは数値化する命令。

$(function(){
$("#d9").css("marginLeft","-300px"); 
//右ボタン
    $("#d13").click(function(){
    if($("#d9").css("marginLeft")=="-1200px"){
    return;
    }else{
    $("#d13").hide();
    $("#d9").animate({marginLeft:parseInt($("#d9").css("marginLeft"))-300+"px"},"slow","swing",
    function(){
    $("#d13").show();
    });
    }
    });
//左ボタン
    $("#d12").click(function(){
    if($("#d9").css("marginLeft")=="0px"){
    return;
    }else{
    $("#d12").hide();
    $("#d9").animate({marginLeft:parseInt($("#d9").css("marginLeft"))+300+"px"},"slow","swing",
    function(){
    $("#d12").show();
    });
    }
    });
});

コメントor補足情報orご指摘あればをお願いします。

(件名or本文内でキーワード検索できます)



  • << 前のページ
  • 次のページ >>
ページトップへ