jQueryでカレンダーを作る ~パート1~
今回はjqueryを使ってカレンダーを作成していきたいと思います。- 1htmlを用意
- 2jqueryのコード
- 3コード解説
htmlを用意
まずはhtmlを用意します。
今回は要素として<div class = "calendar"></div>
だけで大丈夫です。
jqueryのコード
お急ぎの方向けにjqueryのコードを貼っておきます。これでカレンダーの骨組みができます。
$(document).ready(function () {
//作成したいカレンダーの年月を入れる
const year = 2000
const month = 2
$(".calendar").html(CreateCalendar(year,month))
});
function CreateCalendar(year,month){
const weeks = ['日', '月', '火', '水', '木', '金', '土']
//取得する月の1日の情報
const startDateOfMonth = new Date(year, month - 1, 1)
//取得する月の最終日の情報
const lastDateOfMonth = new Date(year, month, 0)
//1日の曜日
const startDay = startDateOfMonth.getDay()
//取得する月のカレンダーの行数
const Calendarline = CalendarLine(startDay,lastDateOfMonth.getDate())
var CalendarElement = "<table>"
//カレンダーの曜日の行を作成
CalendarElement += "<tr>"
for (let w = 0; w < 7; w++) {
CalendarElement += "<td>" + weeks[w] + "</td>"
}
CalendarElement += "</tr>"
var currentDate = 1;
for (let line = 0; line < Calendarline;line++){
CalendarElement += "<tr>"
for (let w = 0; w < 7; w++){
//カレンダーの一行目の場合は1日の曜日より前の枠は空欄にする
//最終日を超えた場合の枠も空欄にする
if ((line == 0 && w < startDay)){
CalendarElement += "<td></td>"
}
else if (currentDate > lastDateOfMonth.getDate()){
CalendarElement += "<td></td>"
currentDate++
}
else{
CalendarElement += "<td>"+currentDate+"</td>"
currentDate++
}
}
CalendarElement += "</tr>"
}
return CalendarElement
}
// //1日の曜日とその月の日数を引数にしてその月の行を返す関数
function CalendarLine(startDay,lastDateOfMonth){
//(例)1日が(金)で最終日が31日の場合6行になる。→31日(日)
if (startDay + lastDateOfMonth >= 36){
return 6;
}
//うるう年でない2月の1日が日曜日の場合
else if (startDay + lastDateOfMonth <= 28){
return 4
}
//それ以外はすべて5行
else {
return 5
}
}
このコードで出来上がるカレンダーは以下になります。
cssで装飾をしていないので味気ないですがちゃんとカレンダーですよね。このカレンダーは2000年の2月です。先ほどのコードの4行目と5行目を操作すれば好きな年月のカレンダーができます。コード解説
では一つ一つ解説をしていきましょう。
今回は2000年の2月を想定しています。大まかな流れ
コードを解説する前に大まかな流れを確認したいと思います。
- 月初め(1日)の情報を取得
- 対象の月の最終日は何日なのか(28、29、30、31日のどれか)を取得
- カレンダーの行数を取得
- 1日からカレンダーに日付の要素を追加していく
使用する関数
今回は関数を作成して使用します。
まず一つ目にCreateCalendarという関数を作成して引数にyearとmonthを渡しています。そしてこの関数の中にCalendarLineという関数を作成して対象の月のカレンダーの行を取得する関数を作成します。引数には1日の曜日と最終日の値を渡します。詳しく解説
コードを解説していきます。
まずweeksという配列を作成してそこに曜日を入れていきます。次にDateオブジェクトを作成します。以下のように書くことでそれぞれに日付のデータが入ります。const startDateOfMonth = new Date(year, month - 1, 1)
const lastDateOfMonth = new Date(year, month, 0)
startDateOfMonthには対象の月の1日が入り、lastDateOfMonthには対象の月の最終日が入ります。ここで注意したいポイントですが第二引数の月に注意しましょう。
monthは0から11までの値が入るのでもし2月の情報を入れたい場合は1を入れなければなりません。そのため今回はmonth -1という風に対象の月から1を引いています。対象の月の最終日の取得方法
1日は引数に注意すれば簡単に取得できますが最終日はどうするのかといいますと、
対象の月の次の月の1日から一日戻ればよいのです。イメージはこんな感じです。ではどのように取得するかというとこのように2020年3月0日という情報を入れることにより、2020年3月1日から一日戻った日付を取得できるのです。これによっていちいち面倒なうるう年の計算などをしなくてもよくなります。※もし、自分で最終日を取得したい人は自分で計算式を使って頑張ってください!!1日の曜日を取得
次に取得した1日のデータから曜日を取得しましょう
const startDay = startDateOfMonth.getDay()
このようにすることでstartDateOfMonthからstartDayという曜日のデータが取得できました。
曜日のデータとはここでは数値が入ります。日曜日から0、1、2...と続き土曜日が6にあたります。今回2000年の2月1日は火曜日ですのでstartDayには2が代入されています。カレンダーの行を取得する
CalendarLineという関数でカレンダーの行を取得していきます。
カレンダーの行と先ほどから言っていますが何のことかといいますと、こういうことです。可能性として4行、5行、6行になることが考えられます。実際にコードを見ていきましょうfunction CalendarLine(startDay,lastDateOfMonth){
if (startDay + lastDateOfMonth >= 36){
return 6;
}
else if (startDay + lastDateOfMonth <= 28){
return 4
}
else {
return 5
}
}
引数には1日の曜日(今回は2)と最終日(今回は29)を渡します。
このCalendarLine関数では何をしているのかというと条件によって行の数値を返す働きをしています。6行になる場合
6行になる場合の条件を考えていきます。
皆さんもカレンダーを片手に考えてみましょう。条件としては- 1日が金曜日で最終日が31日
- 1日が土曜日で最終日が30日もしくは31日
4行になる場合
4行になる場合も同様の考え方をします。
条件は- 1日が日曜日で最終日が28日
5行になる場合
5行になる場合は多く存在しますが今回は4行でも6行でもない場合はすべて5行になりますのでelse文で書いていきます。
※丁寧に不等号で示したい方はそのように書いても問題ありません要素を追加する
それでは必要な情報を取得できたので実際に要素を追加していきましょう。
今回はtableタグを使っていきます。<table>
<tr> <td>1</td><td>2</td><td>3</td></tr>
<tr> <td>4</td><td>5</td><td>6</td></tr>
<tr> <td>7</td><td>8</td><td>9</td></tr>
</table>
tableタグは上記のように使用します。trタグは行をtdタグはセルだと思うと理解がしやすいです。
このように縦横をそろえるカレンダーではtableタグが使いやすいのでこれを使っていきます。初めの行を作成
var CalendarElement = "<table>"
CalendarElement += "<tr>"
for (let w = 0; w < 7; w++) {
CalendarElement += "<td>" + weeks[w] + "</td>"
}
CalendarElement += "</tr>"
まずはCalendarElementという変数を宣言しそれらに要素を追加していきます。
はじめは「日月火水木金土」という行を追加したいので初めに作成したweeksという配列を回しながら要素を追加していきます。ここではfor文の解説は割愛します。日付の要素を作成
var currentDate = 1;
for (let line = 0; line < Calendarline;line++){
CalendarElement += "<tr>"
for (let w = 0; w < 7; w++){
if ((line == 0 && w < startDay)){
CalendarElement += "<td></td>"
}
else if (currentDate > lastDateOfMonth.getDate()){
CalendarElement += "<td></td>"
currentDate++
}
else{
CalendarElement += "<td>"+currentDate+"</td>"
currentDate++
}
}
CalendarElement += "</tr>"
}
curentDateという変数を作成します。
これは日付を表すカウンターになるのでインクリメントしていきます。まず始めのfor文ではカレンダーの行の分だけ繰り返します。先ほどCalendarLineで取得した値を使用します。二つの目のfor文では曜日の列の分だけ繰り返します。もちろん7行あります。ここからが少しややこしいのですが一行目の一列目から要素を追加していく動作を条件分岐で追加していきます。- 1行目は1日の曜日に該当するまで(今回は3列目まで)は要素は空のtdタグを追加する。currentDateはインクリメントしない
- 1日の曜日が該当したらそこからtdタグの中に日付を入れる。
- currentDateが最終日を超えたときは空のtdタグを追加する。currentDateはインクリメント(厳密にはどちらでもよい)
html要素に追加する
ここまで来たらあとは楽勝です。
関数の中で以下のように値を返してあげましょう。CalendarElementにはtableタグの要素が文字列で格納されています。return CalendarElement
最初に戻りますがcalendarというクラス名を持つ要素にhtmlを追加してあげましょう
$(".calendar").html(CreateCalendar(year,month))
これで完成です。
次回はcssで装飾していきます。