Table of Contents
カスタムカレンダーアプリケーションを構築するのは、JavaScript、ブラウザ文書オブジェクトモデル(DOM)、クライアント側のデータ永続性を理解し、理解を深める優れた方法です。 WebストレージAPIを活用することで、特にローカルストレージ — 完全に機能的なイベント駆動型カレンダーを作成できます。これにより、バックエンドサーバーやデータベースを必要としないだけで、ブラウザで完全に実行できます。 このチュートリアルでは、HTMLを指示してドラッグアンドドロップイベント管理などの高度な機能を実装するすべてのステップを歩くことができます。
なぜカスタムカレンダーを作成するのですか?
プレビルドされたカレンダーライブラリ(FullCalendarやDayPilotなど)は、迅速なソリューションを提供していますが、ゼロから1つを構築することで、ユーザーインターフェイス、データ処理、およびパフォーマンスを完全に制御できます。また、[]]]オブジェクト、イベントの委任、および[] APIなどのコアJavaScriptコンセプトで、ハンズオン体験を得ることができます。結果アプリは、プロジェクト管理ツール、予約システム、または個人的なジャーナルに拡張することができます。
HTML 構造の設定
きれいなHTMLスケルトンで始まります。カレンダーには、ナビゲーションバー(月替用)、グリッドコンテナ(日数のセル用)、イベント入力フォーム(イベント入力フォーム)の3つのメインコンポーネントが必要です。スタイリングやスクリプトのスマンティッククラス名を持つ要素を使用します。
<div id="calendar">
<div class="calendar-header">
<button id="prevBtn">←</button>
<h2 id="monthYear"></h2>
<button id="nextBtn">→</button>
</div>
<div class="calendar-grid"></div>
<div class="event-form">
<input type="text" id="eventInput" placeholder="Add an event..." />
<button id="saveEvent">Save</button>
</div>
</div>
JavaScriptで動的に「」がポップアップされます。モバイル対応のレイアウトでは、7列のCSSグリッド(週1回)を利用しています。日名(日・土)の1列を予約してください。
カレンダーをCSSで固定する
クリーンで応答性の高いCSSは、生のHTMLを使用可能なインターフェイスに変換します。 カレンダーグリッド用のCSSグリッドを使用して、を設定してください。 月の初旬までにスペーサを追加します。 アクセシビリティーのために、十分な色のコントラストを確保し、インタラクティブな要素のスタイルが含まれています。 最小限のスタイルシートは、以下に示されます(インラインまたはリンク)。
.calendar-grid {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 2px;
}
.day-cell {
min-height: 80px;
border: 1px solid #ccc;
padding: 4px;
position: relative;
}
.day-cell.today {
background-color: #eef;
}
.event {
font-size: 0.8em;
background: #4caf50;
color: #fff;
padding: 2px 4px;
margin: 1px 0;
border-radius: 3px;
cursor: pointer;
}
画面の狭めにセルサイズを小さくし、イベントのテキストを隠してカウントだけを示すためにメディアの問い合わせを使用してください。
コア JavaScript: カレンダーグリッドを生成する
JavaScript で動的なレンダリングが生きます。中央関数 は、月の最初の日と合計日の日を計算します。 を使用して、平日のインデックス (0 = 日曜日) を取得します。その後、月の最後の日に 1 から 1 ループにセルを生成します。
Date オブジェクトで動作する
[ オブジェクトは、カレンダーロジックのバックボーンです。 1ヶ月の最後の日を取得するには、 (翌月の0日目は現在の月の最後の日を与えます) を使用します。 ナビゲーションはそれらを更新することができますので、現在の月と年をグローバル変数に保存します。
グリッドの構築
function renderCalendar() {
const grid = document.querySelector('.calendar-grid');
grid.innerHTML = '';
const firstDay = new Date(currentYear, currentMonth, 1).getDay();
const daysInMonth = new Date(currentYear, currentMonth + 1, 0).getDate();
// Add empty cells for days before the 1st
for (let i = 0; i < firstDay; i++) {
const empty = document.createElement('div');
empty.className = 'day-cell empty';
grid.appendChild(empty);
}
// Generate day cells
for (let day = 1; day <= daysInMonth; day++) {
const cell = document.createElement('div');
cell.className = 'day-cell';
cell.dataset.date = `${currentYear}-${currentMonth + 1}-${day}`;
const dateSpan = document.createElement('span');
dateSpan.textContent = day;
cell.appendChild(dateSpan);
// Highlight today
const today = new Date();
if (currentYear === today.getFullYear() && currentMonth === today.getMonth() && day === today.getDate()) {
cell.classList.add('today');
}
// Load events for this date
loadEvents(cell);
grid.appendChild(cell);
}
}
ヘッダーに月/年表示を更新: []
月間運行
ボタンをオンにすると、イベントリスナーが前後するボタンをクリック。必要に応じて、年を調整するを増加または減少させる。(12月以降は翌年1月に来る)。変数を更新した後、再度を呼び出します。
document.getElementById('prevBtn').addEventListener('click', () => {
currentMonth--;
if (currentMonth < 0) {
currentMonth = 11;
currentYear--;
}
renderCalendar();
});
document.getElementById('nextBtn').addEventListener('click', () => {
currentMonth++;
if (currentMonth > 11) {
currentMonth = 0;
currentYear++;
}
renderCalendar();
});
追加のユーザビリティのために、現在の月にビューをリセットし、現在の日にハイライトする[[]]]を[[[]ボタンを追加します。
ストーリング&ローカルストレージでイベントを回収
[Local Storage]]は、ブラウザの再起動を生き残るシンプルなキー値ストアを提供します。イベントオブジェクトのJSON配列を格納する、例えば、一貫性のあるキーパターンを使用します。 ]]、 、 []]などのプロパティを含める。
新規イベントの保存
ユーザーが「保存」ボタンをクリックすると、入力値と現在選択されている日付をキャプチャします。(日付ピッカーを追加したり、クリックした日付のセルを検出することができます。) ローカルストレージからその日付の既存のイベントをリトリビューし、新しいイベントをプッシュしてから、保存します。
function saveEvent(dateKey, eventText) {
const existing = JSON.parse(localStorage.getItem(dateKey)) || [];
existing.push({ id: Date.now(), text: eventText, time: new Date().toLocaleTimeString() });
localStorage.setItem(dateKey, JSON.stringify(existing));
renderCalendar(); // refresh to show new event
}
日数のセルにイベントをロードする
[ 内の非空日セルは、その日付キーのローカルストレージをクエリする関数を呼び出します。イベントが存在する場合は、それらを通してループし、セルに 要素を追加します。
function loadEvents(cell) {
const dateKey = cell.dataset.date;
const events = JSON.parse(localStorage.getItem(dateKey));
if (!events) return;
events.forEach(evt => {
const eventDiv = document.createElement('div');
eventDiv.className = 'event';
eventDiv.textContent = evt.text;
eventDiv.dataset.id = evt.id;
// Optional: add a delete button
cell.appendChild(eventDiv);
});
}
イベントの削除と編集
削除するには、イベント要素にクリックイベントを添付(またはイベントの委任を使用する)。その日付の配列を取得するには、イベントをでフィルタアウトし、更新された配列をローカルストレージに保存します。編集は、イベントをダブルクリックして、新しいテキストをプロンプトで実行し、配列を更新することができます。
機能性を高めるための高度な機能
基本的なカレンダーが機能したら、ユーザーエクスペリエンスを大幅に向上させる機能を追加できます。
種類別カラーコーディングイベント
ユーザーがカテゴリ(例、仕事、個人、健康)を割り当てることを可能にします。 フィールドをローカルストレージに保存します。 CSS では、、 ] などのクラスを定義し、動的にそれらを適用します。
ドラッグ&ドロップリスケジュール
デイセル間でイベントを移動するには、HTML5ドラッグ&ドロップAPIを使用します。イベントが異なる日にドロップされると、ローカルストレージの日付キーを更新します。イベントを元の日付配列から削除し、新しい日付の配列にプッシュします。
再発イベント(週毎/月)
イベントを保存する際に「Repeat」オプションを追加します。 ロード機能では、現在の日付が再発ルール(例えば、毎週月曜日)に一致し、それに応じてイベントを表示している場合に計算します。 重複を避けるために、別のローカルストレージキーで再発ルールを保存します。
週ビューとミニカレンダー
月と週のビューを切り替えます。週ビューは、現在の週の日だけを水平なスペースで表示します。小さな月ビューミニカレンダーは、ユーザーがすぐに任意の日付にジャンプするのに役立ちます。
カレンダーの応答性およびアクセシブルを作る
さまざまな画面サイズでカレンダーをテストします。 クエリを使用して、非常に小さな画面上に垂直に日セルをスタックするか、パディングを削減します。 すべてのインタラクティブな要素がキーボードでアクセス可能であることを確認してください。 Enter と Escape の のイベントを添付します。 []] ボタンと画面リーダーのライブ領域の属性を使用して、月間の変更とイベントの追加をアナウンスします。
パフォーマンスとデータ管理のヒント
- [:バッチストレージ書き込み[]:イベントの動作ごとにローカルストレージを読み書きする代わりに、JavaScriptオブジェクトで月のイベント全体をキャッシュし、フラッシュの変更を定期的にキャッシュします。
- [イベントサイズを制限]:イベントオブジェクトを小さく保ちます。大きな文字列やバイナリデータを格納しないでください。
- ストレージの制限のためのフォールバック[:ローカルストレージは通常5〜10 MBでキャプチャされます。ストレージがほぼいっぱいになると、ユーザーは警告します。
- [] 大きいデータセット[ のインデックス化されたDBを使用します。あなたのカレンダーが何千ものイベントを保持する場合、より良いパフォーマンスとクエリ機能のためにをで検討してください。
コンテンツ
JavaScript と Local Storage でカスタム カレンダー アプリを作成すると、フロントエンド スキルをシャープにするやりがいのあるプロジェクトです。 DOM を操作したり、日付とともに作業したり、サーバーなしで状態を管理したり、ユーザー インタラクションを処理したりすることができます。コードベースは、サーバーの同期、クラウド バックアップ、または外部カレンダーとの統合を ]] で拡張できます。基本的なグリッドから始めて、永続性を追加し、その後、ドラッグ 結果がイベントを繰り返すかのようにレイヤーをドラッグ 変更する必要があります。
更に読みたい場合は、MDNの]]のストレージAPIのドキュメントと]のドラッグ&ドロップAPIをMDNで探索してください。 ハッピーコーディング!