ブラウザで動くシンプルな万年カレンダーを作る/素のJavaScript(Vanilla JS)だけ
目次
シンプルな万年カレンダー
出来上がりイメージはこんな感じです。
右の△を押すと、1月先、左の△を押すと1月戻る・・ようにします。
HTML ソース
ベースとなるHTMLです。
<!DOCTYPE HTML> <html> <head> <meta charset="utf8"> <title>ごく簡単なカレンダー</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="bulma/css/bulma.css" /> </head> <body> <section class="hero is-fullheight is-dark"> <div class="hero-body"> <div class="container has-text-centered"> <div class="content"> <table> <tr> <td class="is-one-quarter"> <input type="image" src="images/left-allow.jpg" onclick="dec_month()" /> </td> <td class="is-half"> <div id="title" class="content"></div> </td> <td class="is-one-quarter"> <input type="image" src="images/right-allow.jpg" onclick="inc_month()" /> </td> </tr> </table> </div> <div id="main_body" class="content has-text-centered"> </div> </div> </div> <div class="hero-foot"> <div class="container has-text-centered is-vcentered"> <div class="content"> <p> 2021/02/25 基本の確認をかねてやってみる </p> </div> </div> </div> </section> <script src="js/cal_sample.js"></script> </body> </html>
レイアウトを定義しています。
CSSは「Bulma」を使っています。
ダウンロード後解凍したbulmaフォルダごと、htmlを置いたフォルダにコピーしている想定です。
カレンダー本体は、JavaScriptでHTMLを生成して、「<div id="main_body" class="content has-text-centered"> </div>」のブロック内に出力します。
あと「X月のカレンダー」と表示する部分も、同様にJavaScriptでHTML生成して、「 <div id="title" class="content"></div>」内に出力します。
JavaScriptのソース全体は最後に掲載します。
先に各ポイントごとに説明します。
javascript のポイント1:現在日付情報取得
まずは「現在日付情報の取得」です。
var d_now = new Date() var tmp_n_year = d_now.getFullYear() var tmp_n_month = d_now.getMonth() + 1
日付情報はJavaScriptのDateオブジェクトを使います。
ここで取得するtmp_n_monthは、実際の月を想定していますが、getMonth()が返してくる月は実際の月-1の数字なので、「d_now.getMonth() + 1」としているわけです。
javascriptのポイント2:前月・次月ボタン
HTMLの画像ボタン「 <input type="image" src="images/left-allow.jpg" onclick="dec_month()" />」と「 <input type="image" src="images/left-allow.jpg" onclick="inc_month()" />」で右向きと左向きの△の画像ボタンを作ります。
と みたいな。
このボタンを押すと、月をプラス1かマイナス1して、月間のカレンダーを表示する「disp_cal()」を実行します。
function dec_month() { disp_cal(tmp_n_year, tmp_n_month - 1) } function inc_month() { disp_cal(tmp_n_year, tmp_n_month + 1) }
tmp_n_monthが現在表示中の月を示します。
tmp_n_monthは、disp_cal()の中で更新して、現在表示中の月を保持しています。
javascriptのポイント3:月間カレンダー表示
現在日付の年・月を初期値にカレンダー表示する部分です。
この部分は「disp_cal(year,month)」という名前の関数で定義します。
function disp_cal(year, month) { tmp_n_year = year tmp_n_month = month var d_date = new Date(tmp_n_year, tmp_n_month - 1, 1) var n_dayOfWeek = d_date.getDay() var n_month = d_date.getMonth() var n_year = d_date.getFullYear()
const n_base_month = d_date.getMonth() document.getElementById('title').innerHTML = '<h1 class="title">' + n_year + '年' + (n_base_month + 1) + '月のカレンダー</h1>' var str_body = '' for (let i = 0; i < 5; i++) { str_body = str_body + '<div class="columns">' for (let j = 0; j < 7; j++) { if (n_dayOfWeek == j && n_base_month == n_month) { if (n_dayOfWeek == 0) { str_body = str_body + '<div class="column" ' + 'style="height:80px;color:yellow;' + 'border-bottom:solid white;border-left:solid white;border-right:solid white;"><p>' + d_date.getDate() + '</p></div>' } else { if (n_dayOfWeek == 6) { str_body = str_body + '<div class="column" ' + 'style="height:80px;color:yellow;' + 'border-bottom:solid white;border-right:solid white;"><p>' + d_date.getDate() + '</p></div>' } else { str_body = str_body + '<div class="column" ' + 'style="height:80px;border-bottom:solid;border-right:solid;"><p>' + d_date.getDate() + '</p></div>' } } d_date.setDate(d_date.getDate() + 1) n_dayOfWeek = d_date.getDay() n_month = d_date.getMonth() } else { if (n_dayOfWeek == 0 || j == 0) { str_body = str_body + '<div class="column" ' + 'style="height:80px;border-bottom:solid;border-left:solid;border-right:solid;">' + '<p>-</p></div>' } else { if (n_dayOfWeek == 6) { str_body = str_body + '<div class="column" ' + 'style="height:80px;border-bottom:solid;border-right:solid;"><p>-</p></div>' } else { str_body = str_body + '<div class="column" ' + 'style="height:80px;border-bottom:solid;border-right:solid;"><p>-</p></div>' } } } } str_body = str_body + '</div>' } var ar_dayOfWeek = ['日', '月', '火', '水', '木', '金', '土'] var str_head = '<div class="columns">' for (let t = 0; t < 7; t++) { str_head = str_head + '<div class="column" style="height:60px;border-bottom:solid;"><p>' + ar_dayOfWeek[t] + '</p></div>' } str_head = str_head + '</div>' str_body = str_head + str_body document.getElementById('main_body').innerHTML = str_body }
とりあえずポイントです。
tmp_n_year = year
tmp_n_month = month
引数をカレントの年・月を保持する変数にセットしています。
「var」で定義した変数はfunctionの外で定義していても、参照更新できます。
(lブロックスコープの「let」は、forループのカウンタ等に使ってます。)
それを使って、指定の年・月の1日の日付を取得します。
tmp_n_monthには「2月なら2」「3月なら3」のように人が認識するのと同じ月をセットしていますが、Dateオブジェクトの引数にするときは「2月なら1」「3月なら2」のようにマイナス1しないといけないので、以下のようになってます。
var d_date = new Date(tmp_n_year, tmp_n_month - 1, 1)
var n_dayOfWeek = d_date.getDay()
var n_month = d_date.getMonth()
var n_year = d_date.getFullYear()
javascriptのポイント4:タイトルの表示
タイトル部分の表示です。
const n_base_month = d_date.getMonth()
document.getElementById('title').innerHTML = '<h1 class="title">' + n_year + '年' + (n_base_month + 1) + '月のカレンダー</h1>'
HTMLのタグを文字列で生成して、innerHTMLで上書きしてます。
Dateオブジェクトの「getDay()」で曜日(0-6 0が日曜)を返すので、それにあわせて日曜始まりの枠を作ってます。
var ar_dayOfWeek = ['日', '月', '火', '水', '木', '金', '土']
var str_head = '<div class="columns">'
for (let t = 0; t < 7; t++) {
str_head = str_head
+ '<div class="column" style="height:60px;border-bottom:solid;"><p>'
+ ar_dayOfWeek[t] + '</p></div>'
}
str_head = str_head + '</div>'
あとは、7日×5行の枠を作るループをまわすと。
for (let i = 0; i < 5; i++) {
for (let j = 0; j < 7; j++) {・・・・
}
}
内側の変数「j」が曜日(0-6)に対応するので、日にちを1日ずつすすめながら、
d_date.setDate(d_date.getDate() + 1)
n_dayOfWeek = d_date.getDay()
getDay()で取得した曜日と変数[j」の値が一致するところに書き込むHTMLを生成して文字列として連結して、最後にinnerHTMLに上書きする・・というわけです。
で。
n_month = d_date.getMonth()
上記で取得するn_monthの値(月)が、指定の月(base_month)と一致している間だけ繰り返すと、ちょうどひと月分のカレンダーになります。
HTMLを生成するときに、ちょっと面倒なのが「border」の引き方です。
普通に「border」ってするだけだと、隣り合う線が重複して太くなって不細工なので、基本bottomとrightのみ線を引いて、一番左端(j=0)の場合のみleftも引く・・みたいなことをやって、体裁を整えてます。
とりあえず。
こんなところでしょうか。
javascriptソース全体
最後に「cal_sample.js」全体をのせておきます。
function dec_month() { disp_cal(tmp_n_year, tmp_n_month - 1) } function inc_month() { disp_cal(tmp_n_year, tmp_n_month + 1) } function disp_cal(year, month) { tmp_n_year = year tmp_n_month = month var d_date = new Date(tmp_n_year, tmp_n_month - 1, 1) var n_dayOfWeek = d_date.getDay() var n_month = d_date.getMonth() var n_year = d_date.getFullYear() const n_base_month = d_date.getMonth() document.getElementById('title').innerHTML = '<h1 class="title">' + n_year + '年' + (n_base_month + 1) + '月のカレンダー</h1>' var str_body = '' for (let i = 0; i < 5; i++) { str_body = str_body + '<div class="columns">' for (let j = 0; j < 7; j++) { if (n_dayOfWeek == j && n_base_month == n_month) { if (n_dayOfWeek == 0) { str_body = str_body + '<div class="column" ' + 'style="height:80px;color:yellow;' + 'border-bottom:solid white;border-left:solid white;border-right:solid white;"><p>' + d_date.getDate() + '</p></div>' } else { if (n_dayOfWeek == 6) { str_body = str_body + '<div class="column" ' + 'style="height:80px;color:yellow;' + 'border-bottom:solid white;border-right:solid white;"><p>' + d_date.getDate() + '</p></div>' } else { str_body = str_body + '<div class="column" ' + 'style="height:80px;border-bottom:solid;border-right:solid;"><p>' + d_date.getDate() + '</p></div>' } } d_date.setDate(d_date.getDate() + 1) n_dayOfWeek = d_date.getDay() n_month = d_date.getMonth() } else { if (n_dayOfWeek == 0 || j == 0) { str_body = str_body + '<div class="column" ' + 'style="height:80px;border-bottom:solid;border-left:solid;border-right:solid;">' + '<p>-</p></div>' } else { if (n_dayOfWeek == 6) { str_body = str_body + '<div class="column" ' + 'style="height:80px;border-bottom:solid;border-right:solid;"><p>-</p></div>' } else { str_body = str_body + '<div class="column" ' + 'style="height:80px;border-bottom:solid;border-right:solid;"><p>-</p></div>' } } } } str_body = str_body + '</div>' } var ar_dayOfWeek = ['日', '月', '火', '水', '木', '金', '土'] var str_head = '<div class="columns">' for (let t = 0; t < 7; t++) { str_head = str_head + '<div class="column" style="height:60px;border-bottom:solid;"><p>' + ar_dayOfWeek[t] + '</p></div>' } str_head = str_head + '</div>' str_body = str_head + str_body document.getElementById('main_body').innerHTML = str_body } var d_now = new Date() var tmp_n_year = d_now.getFullYear() var tmp_n_month = d_now.getMonth() + 1 disp_cal(tmp_n_year, tmp_n_month)
素のJavaScript(Vanilla JS)でやってます。
ではでは。
#JS