11
1

【JavaScript】カレンダーをtemplateタグでつくってみた

Last updated at Posted at 2023-12-22

このたび 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タグ

calendar.html
<template id="oneWeek">
    <tr>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
      <td></td>
    </tr>
</template>

templateタグを使ったJavaScriptのコード

calendar.js
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タグを使った方法を試してみてください!

参考記事

11
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
1