このたび templateタグを使って カレンダーを作成してみました。
「カレンダー作成 js」と検索してもあまり出てこないやり方ですが、いくつかのメリットがあったので紹介します。
templateタグを使うメリット
templateタグには次のようなメリットがあります。
js側でタグを文字列から生成せずに済む
同じ構造のHTMLを使い回せる
💁♀️ < 詳しく説明します
① js側でタグを文字列から生成せずに済む
例えば、DOM要素をつくるためのコードを以下のように書くとします。
let calendarHtml = document.querySelector('#calendarHtml'); // DOMを作成したい位置
calendarHtml.innerHTML = '<td>新しいDOM</td>';
このようにタグ記法の文字列を直接入力する場合、少しハードコーディング気味になってしまいます。また、条件を付け足したい時、文字列結合だとDOM操作ができないのでやや不便です。
templateタグを使うことで、HTMLからDOM要素を読み込み・操作できるため、これらの問題がクリアされます。
② 同じ構造のHTMLを使い回せる
同じ構造が何回か続く場合、一回分のtemplateだけを用意すれば使用する時にクローンして使い回せるので、記述するHTMLが最小限で済みます。
実際にカレンダーをつくってみた
See the Pen カレンダー by 山下茉莉花 (@uhhpnrer-the-flexboxer) on CodePen.
条件
- 月初日より前の日付は何も記述しない
- 当日に印をつける
- 今日以降の日付をグレーアウトにする
用意したtemplateタグ
<template id="oneWeek">
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</template>
templateタグを使ったJavaScriptのコード
const date = new Date();
const year = date.getFullYear();
const month = date.getMonth() + 1;
const calendarHeader = document.querySelector(".calendarHeader");
calendarHeader.textContent = `${year}年${month}月`;
// 月末日を取得
const totalDatesInMonth = new Date(year, month, 0).getDate();
const calendarHtml = document.querySelector("#calendar");
const tbody = document.querySelector("#tableBody");
// 日にちのカウント
let dayCount = 1;
const weekArray = [];
while (dayCount <= totalDatesInMonth) {
const targetDate = new Date(year, month - 1, dayCount);
// その月の第何週目かを取得
const week = Math.floor((targetDate.getDate() - targetDate.getDay() + 12) / 7);
// 'oneWeek'templateをクローンして作成
const weekHtml = document.querySelector("#oneWeek");
const weekTemplate = weekHtml.content.cloneNode(true);
weekArray[week - 1] ||= weekTemplate;
// 現在まわしている日付が第何週目の何曜日かを取得
const targetCell = weekArray[week - 1].querySelector(`td:nth-of-type(${targetDate.getDay() + 1})`);
// 日付をテキスト
targetCell.textContent = `${dayCount}`;
// targetCellが今日だった場合印をつける
if (targetDate.toDateString() === date.toDateString())
targetCell.classList.add("today");
// targetCellが今日以降だった場合グレーアウトにする
if (targetDate > date) targetCell.classList.add("disable");
dayCount ++;
}
weekArray.forEach((week) => {
tbody.appendChild(week);
});
感想
templateタグを使うことで、js側でタグを文字列で生成せずに済み, 何度も同じHTMLを記述する必要がなくなったため、シンプルで良いコードになった気がします。
カレンダー作成をしようと思っている人、ぜひ一度templateタグを使った方法を試してみてください!
参考記事