文章标题:
HTML日历活动页面搭建(附源码)
文章内容:
目录
-
- 专栏导言
- 项目概述
- 功能特征
-
- 🗓️ 关键功能
- ✨ 特色功能
- 技术施行
-
- 技术组合
- 核心技术要点
-
- 1. 日历绘制算法
- 2. 悬停提示功能达成
- 3. CSS动画与样式设计
- 项目架构
- 开发亮点
-
- 1. 面向对象设计
- 2. 事件驱动架构
- 3. 数据持久化
- 4. 响应式布局
- 5. 用户体验优化
- 使用办法
- 技术特性
-
- 智能提示框定位
- 优雅的动画效果
- 现代化UI设计
- 浏览器兼容性
- 未来拓展
- 总结
- 源码
-
- index.html
- script.js
- style.css
专栏导言
🌸 欢迎来到Python办公自动化相关专栏—在此可学习用Python解决办公场景问题,助力提升工作效率
🏳️🌈 博主博客主页:请点击访问——>
一晌小贪欢的个人博客主页,欢迎关注
👍
本系列文章所属专栏:请点击查看——>Python办公自动化相关专栏,期待您的订阅
🕷
另有爬虫相关专栏:请点击查看——>Python爬虫基础专栏,欢迎订阅
📕
还有Python基础学习专栏:请点击查看——>Python基础学习专栏,欢迎订阅
文章作者技术尚有不足,文中若有错误,还望大家批评指正🙏
❤️ 欢迎各位朋友关注! ❤️
项目概述
-
这是一款功能完善的日历计划管理应用,采用纯前端技术架构开发,支持对活动进行增删改查操作,且具备智能的悬停提示功能。用户可直观查看每日活动安排,将鼠标悬停在对应日期可快速预览活动详情。
功能特征
🗓️ 关键功能
- 月份切换 :支持便捷地前后切换月份进行浏览
- 日期选择 :点击日期即可选中并设定为活动日期
- 活动管理 :实现完整的创建、读取、更新、删除(CRUD)操作
- 今日高亮 :自动标记当前日期
- 活动指示器 :有活动安排的日期显示红色圆点标记
✨ 特色功能
- 悬停提示 :鼠标悬停在有活动的日期上时,显示活动详情提示框
- 本地存储 :运用localStorage实现数据持久化存储
- 响应式设计 :适配不同屏幕尺寸设备
- 优雅动画 :具备流畅过渡效果与良好交互反馈
技术施行
技术组合
- HTML5 :利用语义化标签构建页面结构
- CSS3 :借助现代样式特性,包含Grid布局、动画效果等
- JavaScript ES6+ :采用面向对象编程方式,进行模块化代码组织
核心技术要点
1. 日历绘制算法
renderCalendar() {
const year = this.currentDate.getFullYear();
const month = this.currentDate.getMonth();
// 获取月份第一天和最后一天
const firstDay = new Date(year, month, 1);
const lastDay = new Date(year, month + 1, 0);
const startDate = new Date(firstDay);
startDate.setDate(startDate.getDate() - firstDay.getDay());
// 生成42天(6周)的完整日历视图
for (let i = 0; i < 42; i++) {
const date = new Date(startDate);
date.setDate(startDate.getDate() + i);
const dayElement = this.createDayElement(date, month);
calendarDays.appendChild(dayElement);
}
}
2. 悬停提示功能达成
addHoverTooltip(dayElement, events) {
let tooltip = null;
dayElement.addEventListener('mouseenter', (e) => {
// 创建提示框
tooltip = document.createElement('div');
tooltip.className = 'event-tooltip';
const tooltipContent = events.map(event => {
return `<div class="tooltip-event">
<div class="tooltip-title">${event.title}</div>
<div class="tooltip-time">${event.time || '时间未设置'}</div>
</div>`;
}).join('');
tooltip.innerHTML = tooltipContent;
document.body.appendChild(tooltip);
// 智能定位提示框
const rect = dayElement.getBoundingClientRect();
tooltip.style.left = rect.left + rect.width / 2 + 'px';
tooltip.style.top = rect.top - 10 + 'px';
});
dayElement.addEventListener('mouseleave', () => {
if (tooltip) {
document.body.removeChild(tooltip);
tooltip = null;
}
});
}
3. CSS动画与样式设计
.event-tooltip {
position: absolute;
background: rgba(0, 0, 0, 0.9);
color: white;
padding: 10px;
border-radius: 8px;
font-size: 12px;
z-index: 1000;
max-width: 200px;
transform: translateX(-50%) translateY(-100%);
pointer-events: none;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
animation: tooltipFadeIn 0.2s ease;
}
@keyframes tooltipFadeIn {
from {
opacity: 0;
transform: translateX(-50%) translateY(-100%) scale(0.9);
}
to {
opacity: 1;
transform: translateX(-50%) translateY(-100%) scale(1);
}
}
项目架构
日历计划表项目/
├── index.html # 主页面结构文件
├── style.css # 样式文件
├── script.js # 核心逻辑文件
开发亮点
1. 面向对象设计
- 运用ES6 Class语法,将日历功能封装在
CalendarApp
类中,代码结构清晰,便于维护与扩展
2. 事件驱动架构
- 通过设置事件监听器处理用户交互操作,涵盖点击、悬停、表单提交等操作的响应处理
3. 数据持久化
- 利用
localStorage
实现客户端数据存储,确保用户数据在浏览器关闭后仍保留
4. 响应式布局
- 采用CSS Grid和Flexbox布局,结合媒体查询实现多设备适配
5. 用户体验优化
- 平滑的动画过渡效果
- 直观的视觉反馈
- 智能的提示框定位
- 优雅的交互设计
使用办法
- 添加活动 :填写活动表单,点击"添加活动"按钮
- 查看活动 :点击有红点标记的日期查看详情,或鼠标悬停快速预览
- 删除活动 :点击活动详情中的"删除活动"按钮
- 切换月份 :使用左右箭头按钮浏览不同月份
技术特性
智能提示框定位
提示框依据日期元素位置自动调整显示位置,确保任何情况下都能完整展示内容
优雅的动画效果
- 日期悬停时的缩放效果
- 提示框的淡入动画
- 按钮的悬停反馈效果
- 模态框的滑入效果
现代化UI设计
- 运用渐变背景与阴影效果
- 采用圆角设计风格
- 合理的色彩搭配
- 清晰的信息层级划分
浏览器兼容性
- Chrome 60+
- Firefox 55+
- Safari 12+
- Edge 79+
未来拓展
- 添加活动分类与颜色标记
- 支持重复活动设置
- 集成提醒功能
- 实现数据导入导出
- 支持多语言
总结
-
该日历计划管理项目展现现代前端开发最佳实践,通过合理架构设计、美观用户界面与流畅交互体验,为用户提供实用美观的日程管理工具。悬停提示功能提升用户体验,使活动信息查看更便捷高效。
技术栈:HTML5 + CSS3 + JavaScript ES6+
源码
index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>日历计划表</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<header>
<h1>我的日历计划表</h1>
</header>
<div class="calendar-controls">
<button id="prevMonth"><</button>
<h2 id="currentMonth"></h2>
<button id="nextMonth">></button>
</div>
<div class="calendar-grid">
<div class="weekdays">
<div>日</div>
<div>一</div>
<div>二</div>
<div>三</div>
<div>四</div>
<div>五</div>
<div>六</div>
</div>
<div id="calendarDays" class="days"></div>
</div>
<div class="event-section">
<h3>添加活动</h3>
<form id="eventForm">
<input type="date" id="eventDate" required>
<input type="text" id="eventTitle" placeholder="活动标题" required>
<input type="time" id="eventTime">
<textarea id="eventDescription" placeholder="活动描述"></textarea>
<button type="submit">添加活动</button>
</form>
</div>
<div class="events-list">
<h3>今日活动</h3>
<div id="todayEvents"></div>
</div>
</div>
<!-- 活动详情模态框 -->
<div id="eventModal" class="modal">
<div class="modal-content">
<span class="close">×</span>
<h3>活动详情</h3>
<div id="eventDetails"></div>
<button id="deleteEvent">删除活动</button>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
script.js
```javascript
class CalendarApp {
constructor() {
this.currentDate = new Date();
this.selectedDate = null;
this.events = JSON.parse(localStorage.getItem('calendarEvents')) || {};
this.init();
}
init() {
this.bindEvents();
this.renderCalendar();
this.updateTodayEvents();
}
bindEvents() {
// 月份切换
document.getElementById('prevMonth').addEventListener('click', () => {
this.currentDate.setMonth(this.currentDate.getMonth() - 1);
this.renderCalendar();
});
document.getElementById('nextMonth').addEventListener('click', () => {
this.currentDate.setMonth(this.currentDate.getMonth() + 1);
this.renderCalendar();
});
// 活动表单提交
document.getElementById('eventForm').addEventListener('submit', (e) => {
e.preventDefault();
this.addEvent();
});
// 模态框关闭
document.querySelector('.close').addEventListener('click', () => {
this.closeModal();
});
document.getElementById('eventModal').addEventListener('click', (e) => {
if (e.target === document.getElementById('eventModal')) {
this.closeModal();
}
});
// 删除活动
document.getElementById('deleteEvent').addEventListener('click', () => {
this.deleteCurrentEvent();
});
}
renderCalendar() {
const year = this.currentDate.getFullYear();
const month = this.currentDate.getMonth();
// 更新月份标题
const monthNames = [
'一月', '二月', '三月', '四月', '五月', '六月',
'七月', '八月', '九月', '十月', '十一月', '十二月'
];
document.getElementById('currentMonth').textContent = `${year}年 ${monthNames[month]}`;
// 获取月份第一天和最后一天
const firstDay = new Date(year, month, 1);
const lastDay = new Date(year, month + 1, 0);
const startDate = new Date(firstDay);
startDate.setDate(startDate.getDate() - firstDay.getDay());
// 清空日历
const calendarDays = document.getElementById('calendarDays');
calendarDays.innerHTML = '';
// 生成42天(6周)
for (let i = 0; i < 42; i++) {
const date = new Date(startDate);
date.setDate(startDate.getDate() + i);
const dayElement = this.createDayElement(date, month);
calendarDays.appendChild(dayElement);
}
}
createDayElement(date, currentMonth) {
const dayDiv = document.createElement('div');
dayDiv.className = 'day';
const dayNumber = document.createElement('div');
dayNumber.className = 'day-number';
dayNumber.textContent = date.getDate();
dayDiv.appendChild(dayNumber);
// 添加样式类
if (date.getMonth() !== currentMonth) {
dayDiv.classList.add('other-month');
}
if (this.isToday(date)) {
dayDiv.classList.add('today');
}
// 检查是否有活动
const dateKey = this.formatDate(date);
if (this.events[dateKey] && this.events[dateKey].length > 0) {
const indicator = document.createElement('div');
indicator.className = 'event-indicator';
dayDiv.appendChild(indicator);
// 添加悬停显示活动详情功能
this.addHoverTooltip(dayDiv, this.events[dateKey]);
}
// 点击事件
dayDiv.addEventListener('click', () => {
this.selectDate(date);
});
return dayDiv;
}
addHoverTooltip(dayElement, events) {
let tooltip = null;
dayElement.addEventListener('mouseenter', (e) => {
// 创建提示框
tooltip = document.createElement('div');
tooltip.className = 'event-tooltip';
const tooltipContent = events.map(event => {
return `<div class="tooltip-event">
<div class="tooltip-title">${event.title}</div>
<div class="tooltip-time">${event.time || '时间未设置'}</div>
</div>`;
}).join('');
tooltip.innerHTML = tooltipContent;
document.body.appendChild(tooltip);
// 定位提示框
const rect = dayElement.getBoundingClientRect();
tooltip.style.left = rect.left + rect.width / 2 + 'px';
tooltip.style.top = rect.top - 10 + 'px';
});
dayElement.addEventListener('mouseleave', () => {
if (tooltip) {
document.body.removeChild(tooltip);
tooltip = null;
}
});
}
selectDate(date) {
// 移除之前的选中状态
document.querySelectorAll('.day.selected
相关文章
暂无评论...