日曆已成為現代 Web 應用程式中不可或缺的一部分,因為它們使用戶能夠無縫地組織、安排和追踪事件。無論您是在建立專案管理工具、事件排程應用程式還是個人生產力套件,自定義日曆元件都可以大大增強用戶體驗。儘管存在許多現成的日曆庫,但創建自己的元件可以提供滿足特定設計和功能需求的靈活性。
在本教程中,我們將探索如何使用 JavaScript 構建類似 Google 日曆的元件。通過本指南的最後,您將擁有一個具有互動功能的完全功能日曆,並更深入了解如何為您的 Web 應用程式構建可重複使用的元件。無論您是開發人員,希望為您的項目增加獨特的特色,還是渴望了解日曆功能的內部運作,這個逐步指南都將是無價的。讓我們開始吧!
概述
我們將創建一個具有以下功能的日曆元件:
- 時間軸:從凌晨 12 點到晚上 11 點的垂直時間軸。
- 事件區塊:根據它們的開始和結束時間,動態呈現事件並具有適當的位置和高度。
- 重疊處理:時間上重疊的事件將並排出現。
以下是您可以逐步創建此元件的步驟。
逐步指南
1. 設置 HTML 和基本樣式
我們開始創建一個簡單的 HTML 結構 用於日曆。該佈局包括時間軸和事件容器。
<div class="calendar">
<div class="calendar-time">
<ul id="timelist" class="calendar-timelist"></ul>
</div>
<div id="events" class="calendar-events"></div>
</div>
添加基本的 CSS 來為日曆進行樣式設置:
.calendar {
display: flex;
width: 500px;
margin: 20px auto;
position: relative;
}
.event {
background: #039be5;
border: 1px solid white;
border-radius: 5px;
position: absolute;
box-sizing: border-box;
color: white;
overflow: hidden;
padding: 3px;
}
.calendar-time {
border-right: 1px solid #ccc;
width: 100px;
}
.calendar-timelist {
list-style: none;
padding: 0;
margin: 0;
text-align: right;
padding-right: 20px;
}
.calendar-timelist li {
height: 60px;
box-sizing: border-box;
width: 100%;
}
.calendar-events {
flex-grow: 1;
position: relative;
}
2. 創建日曆的 JavaScript 類
定義一個 Calendar
類來封裝所有功能。
構造函數
構造函數通過渲染時間軸和事件來初始化日曆:
class Calendar {
constructor(data) {
// Render the timeline on the Y-axis
this.renderTime();
// Render the event blocks
this.renderEvents(data);
}
renderTime() {
let timeHTML = Array.from({ length: 24 }, (_, i) => `<li>${this.to12HourFormat(i)}</li>`).join("");
document.getElementById("timelist").innerHTML = timeHTML;
}
renderEvents(data) {
let groupedEvents = this.groupEvents(data);
let eventData = this.calculateEventStyles(groupedEvents);
let eventHTML = eventData
.map(
(e) =>
`<div class="event" style="top: ${e.top}px; height: ${e.height}px; width: ${e.width}%; left: ${e.left}%; z-index: ${e.zIndex};">
<strong>${e.title}</strong><br>${e.time}
</div>`
)
.join("");
document.getElementById("events").innerHTML = eventHTML;
}
to12HourFormat(hour) {
if (hour === 0) return "12 AM";
if (hour < 12) return `${hour} AM`;
if (hour === 12) return "12 PM";
return `${hour - 12} PM`;
}
}
3. 處理事件重疊和定位
我們需要邏輯來處理重疊事件。這是通過分組和計算適當位置來實現的。
按開始小時分組事件
groupEvents(data) {
let groups = [];
data.forEach((event) => {
let hour = parseInt(event.start.split(":")[0], 10);
if (!groups[hour]) groups[hour] = [];
groups[hour].push(event);
});
return groups;
}
計算事件樣式
對於每個組,根據時間和重疊計算事件的 top
、height
、width
和 left
。
calculateEventStyles(groups) {
let eventData = [];
groups.forEach((group) => {
let columns = [];
group.forEach((event) => {
let { start, end } = event;
let [sh, sm] = start.split(":").map(Number);
let [eh, em] = end.split(":").map(Number);
let top = sh * 60 + sm; // Convert start time to minutes
let height = (eh * 60 + em) - top; // Calculate duration in minutes
let left = columns.findIndex((col) => col.end <= start);
if (left === -1) {
left = columns.length;
columns.push({ end });
} else {
columns[left].end = end;
}
eventData.push({
title: event.name,
time: `${this.to12HourFormat(sh)} - ${this.to12HourFormat(eh)}`,
top,
height,
left: (left * 100) / columns.length,
width: 100 / columns.length,
zIndex: left,
});
});
});
return eventData;
}
4. 示例數據和初始化
定義您的事件數據並初始化 Calendar
:
const events = [
{ name: "Meeting with Donna", start: "09:00", end: "10:30" },
{ name: "Project Sync", start: "10:00", end: "11:00" },
{ name: "Lunch Break", start: "12:00", end: "13:00" },
{ name: "Client Call", start: "11:30", end: "12:30" },
];
new Calendar(events);
5. 完整代碼示例
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css">
<title>Calendar Component</title>
</head>
<body>
<div class="calendar">
<div class="calendar-time">
<ul id="timelist" class="calendar-timelist"></ul>
</div>
<div id="events" class="calendar-events"></div>
</div>
<script src="script.js"></script>
</body>
</html>
結論
這種方法使用純 JavaScript 動態生成一個類似 Google 日曆的組件。通過將問題分解為渲染時間、事件分組和計算樣式,您可以構建可擴展的互動組件。您可以實驗這段代碼,添加可拖動事件或額外樣式等功能!
Source:
https://dzone.com/articles/building-a-google-calendar-like-component-using-javascript