旗下品牌:
石家庄网站开发 石家庄网站开发公司

资讯动态

察而思、思而行、行而后语、知行合一

FullCalendar 日历应用

发布时间:2025-08-08 热度:

我将创建一个使用FullCalendar库的现代化日历应用,包含事件管理、主题切换等功能。

设计思路

  • 使用FullCalendar v5展示日历视图

  • 添加事件管理功能(增删改查)

  • 实现亮色/暗色主题切换

  • 设计响应式布局适配不同设备

  • 添加直观的操作界面

下面是完整的实现代码:

html

 

<!DOCTYPE html> <html> <head>     <meta charset="UTF-8">     <meta name="viewport" content="width=device-width, initial-scale=1.0">     <title>FullCalendar 日历应用</title>     <!-- FullCalendar 核心样式 -->     <link href="https://cdn.jsdelivr.net/npm/fullcalendar@5.10.1/main.min.css" rel="stylesheet">     <!-- Google Fonts -->     <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&family=Material+Icons&display=swap" rel="stylesheet">     <style>         :root {             --primary-color: #4361ee;             --secondary-color: #3f37c9;             --accent-color: #4895ef;             --success-color: #4cc9f0;             --text-color: #333;             --bg-color: #f8f9fa;             --card-bg: #ffffff;             --border-color: #e0e0e0;             --shadow: 0 4px 12px rgba(0,0,0,0.08);             --event-color: #4361ee;         }         .dark-theme {             --primary-color: #4895ef;             --secondary-color: #4361ee;             --accent-color: #3f37c9;             --success-color: #4cc9f0;             --text-color: #e0e0e0;             --bg-color: #121212;             --card-bg: #1e1e1e;             --border-color: #333;             --shadow: 0 4px 12px rgba(0,0,0,0.3);             --event-color: #4895ef;         }         * {             margin: 0;             padding: 0;             box-sizing: border-box;         }         body {             font-family: 'Roboto', sans-serif;             background-color: var(--bg-color);             color: var(--text-color);             transition: all 0.3s ease;         }         .container {             max-width: 1400px;             margin: 0 auto;             padding: 20px;         }         header {             display: flex;             justify-content: space-between;             align-items: center;             padding: 20px 0;             margin-bottom: 30px;             border-bottom: 1px solid var(--border-color);         }         .logo {             display: flex;             align-items: center;             gap: 15px;         }         .logo h1 {             font-size: 28px;             font-weight: 700;             background: linear-gradient(45deg, var(--primary-color), var(--success-color));             -webkit-background-clip: text;             background-clip: text;             color: transparent;         }         .logo-icon {             font-size: 32px;             color: var(--primary-color);         }         .controls {             display: flex;             gap: 15px;             align-items: center;         }         .btn {             padding: 10px 20px;             border-radius: 8px;             border: none;             font-weight: 500;             cursor: pointer;             transition: all 0.2s ease;             display: flex;             align-items: center;             gap: 8px;         }         .btn-primary {             background: var(--primary-color);             color: white;         }         .btn-primary:hover {             background: var(--secondary-color);             transform: translateY(-2px);         }         .btn-outline {             background: transparent;             border: 1px solid var(--primary-color);             color: var(--primary-color);         }         .btn-outline:hover {             background: rgba(67, 97, 238, 0.1);         }         .theme-toggle {             width: 50px;             height: 26px;             background: var(--border-color);             border-radius: 13px;             position: relative;             cursor: pointer;         }         .theme-toggle::before {             content: '';             position: absolute;             width: 20px;             height: 20px;             border-radius: 50%;             background: white;             top: 3px;             left: 3px;             transition: all 0.3s ease;         }         .dark-theme .theme-toggle::before {             left: 27px;             background: #333;         }         .main-content {             display: grid;             grid-template-columns: 1fr 350px;             gap: 30px;         }         @media (max-width: 992px) {             .main-content {                 grid-template-columns: 1fr;             }         }         .calendar-container {             background: var(--card-bg);             border-radius: 12px;             padding: 20px;             box-shadow: var(--shadow);             height: 700px;         }         #calendar {             height: 100%;         }         .events-panel {             background: var(--card-bg);             border-radius: 12px;             padding: 25px;             box-shadow: var(--shadow);         }         .panel-title {             font-size: 20px;             margin-bottom: 25px;             padding-bottom: 15px;             border-bottom: 1px solid var(--border-color);             display: flex;             align-items: center;             gap: 10px;         }         .event-form {             display: flex;             flex-direction: column;             gap: 20px;             margin-bottom: 30px;             padding-bottom: 25px;             border-bottom: 1px solid var(--border-color);         }         .form-group {             display: flex;             flex-direction: column;             gap: 8px;         }         .form-group label {             font-weight: 500;             font-size: 15px;         }         .form-group input, .form-group textarea {             padding: 12px;             border-radius: 8px;             border: 1px solid var(--border-color);             background: var(--bg-color);             color: var(--text-color);             font-family: inherit;         }         .form-group textarea {             min-height: 100px;             resize: vertical;         }         .events-list {             display: flex;             flex-direction: column;             gap: 15px;             max-height: 350px;             overflow-y: auto;             padding-right: 10px;         }         .event-item {             background: var(--bg-color);             padding: 15px;             border-radius: 8px;             border-left: 4px solid var(--primary-color);             transition: all 0.2s ease;             cursor: pointer;         }         .event-item:hover {             transform: translateX(5px);         }         .event-title {             font-weight: 500;             margin-bottom: 5px;             display: flex;             justify-content: space-between;         }         .event-time {             font-size: 13px;             color: var(--accent-color);             margin-bottom: 8px;         }         .event-description {             font-size: 14px;             color: var(--text-color);             opacity: 0.9;         }         .color-picker {             display: flex;             gap: 10px;             flex-wrap: wrap;         }         .color-option {             width: 30px;             height: 30px;             border-radius: 50%;             cursor: pointer;             border: 2px solid transparent;             transition: all 0.2s ease;         }         .color-option.active {             border-color: white;             box-shadow: 0 0 0 2px var(--text-color);         }         .no-events {             text-align: center;             padding: 20px;             color: #888;             font-style: italic;         }         footer {             text-align: center;             padding: 30px 0;             margin-top: 50px;             color: #777;             font-size: 14px;             border-top: 1px solid var(--border-color);         }         @media (max-width: 768px) {             header {                 flex-direction: column;                 gap: 20px;             }                          .logo h1 {                 font-size: 24px;             }                          .calendar-container {                 height: 500px;             }         }     </style> </head> <body>     <div>         <header>             <div>                 <span class="logo-icon material-icons">calendar_today</span>                 <h1>FullCalendar 应用</h1>             </div>             <div>                 <button id="prev-btn" class="btn btn-outline">                     <span>chevron_left</span>                     上个月                 </button>                 <button id="today-btn" class="btn btn-outline">                     <span>today</span>                     今天                 </button>                 <button id="next-btn" class="btn btn-outline">                     下个月                     <span>chevron_right</span>                 </button>                 <div id="theme-toggle"></div>             </div>         </header>         <div>             <div>                 <div id="calendar"></div>             </div>                          <div>                 <h2>                     <span>event</span>                     事件管理                 </h2>                                  <div>                     <div>                         <label for="event-title">事件标题</label>                         <input type="text" id="event-title" placeholder="输入事件标题">                     </div>                                          <div>                         <label for="event-description">事件描述</label>                         <textarea id="event-description" placeholder="输入事件描述"></textarea>                     </div>                                          <div>                         <label>事件颜色</label>                         <div>                             <div class="color-option active" style="background-color: #4361ee;" data-color="#4361ee"></div>                             <div style="background-color: #4cc9f0;" data-color="#4cc9f0"></div>                             <div style="background-color: #7209b7;" data-color="#7209b7"></div>                             <div style="background-color: #f72585;" data-color="#f72585"></div>                             <div style="background-color: #2ec4b6;" data-color="#2ec4b6"></div>                             <div style="background-color: #ff9e00;" data-color="#ff9e00"></div>                         </div>                     </div>                                          <button id="add-event" class="btn btn-primary">                         <span>add</span>                         添加事件                     </button>                 </div>                                  <h3>                     <span>list</span>                     事件列表                 </h3>                                  <div id="events-container">                     <div>暂无事件,请添加事件</div>                 </div>             </div>         </div>                  <footer>             <p>© 2023 FullCalendar 日历应用 | 使用 FullCalendar v5 构建</p>         </footer>     </div>     <!-- FullCalendar 核心库 -->     <script src="https://cdn.jsdelivr.net/npm/fullcalendar@5.10.1/main.min.js"></script>     <!-- 中文语言包 -->     <script src="https://cdn.jsdelivr.net/npm/fullcalendar@5.10.1/locales/zh-cn.min.js"></script>          <script>         // 初始化变量         let events = [];         let selectedColor = '#4361ee';                  // DOM 元素         const calendarEl = document.getElementById('calendar');         const eventsContainer = document.getElementById('events-container');         const themeToggle = document.getElementById('theme-toggle');         const prevBtn = document.getElementById('prev-btn');         const nextBtn = document.getElementById('next-btn');         const todayBtn = document.getElementById('today-btn');         const addEventBtn = document.getElementById('add-event');         const eventTitle = document.getElementById('event-title');         const eventDescription = document.getElementById('event-description');         const colorOptions = document.querySelectorAll('.color-option');                  // 初始化日历         const calendar = new FullCalendar.Calendar(calendarEl, {             initialView: 'dayGridMonth',             locale: 'zh-cn',             headerToolbar: {                 left: 'prev,next today',                 center: 'title',                 right: 'dayGridMonth,timeGridWeek,timeGridDay'             },             buttonText: {                 today: '今天',                 month: '月',                 week: '周',                 day: '日'             },             events: events,             eventClick: function(info) {                 // 点击事件时删除                 if (confirm(`确定要删除 "${info.event.title}" 事件吗?`)) {                     info.event.remove();                     events = events.filter(e => e.id !== info.event.id);                     renderEvents();                 }             },             dateClick: function(info) {                 // 点击日期时自动填充日期                 eventTitle.focus();                 alert(`您选择了日期: ${info.dateStr}`);             },             eventDisplay: 'block',             eventColor: selectedColor         });                  calendar.render();                  // 主题切换         themeToggle.addEventListener('click', function() {             document.body.classList.toggle('dark-theme');             // 更新日历主题             const theme = document.body.classList.contains('dark-theme') ? 'dark' : 'light';             calendar.setOption('themeSystem', theme);         });                  // 导航按钮         prevBtn.addEventListener('click', function() {             calendar.prev();         });                  nextBtn.addEventListener('click', function() {             calendar.next();         });                  todayBtn.addEventListener('click', function() {             calendar.today();         });                  // 颜色选择         colorOptions.forEach(option => {             option.addEventListener('click', function() {                 colorOptions.forEach(opt => opt.classList.remove('active'));                 this.classList.add('active');                 selectedColor = this.dataset.color;             });         });                  // 添加事件         addEventBtn.addEventListener('click', function() {             const title = eventTitle.value.trim();             const description = eventDescription.value.trim();                          if (!title) {                 alert('请输入事件标题');                 return;             }                          const newEvent = {                 id: Date.now().toString(),                 title: title,                 description: description,                 start: new Date(),                 color: selectedColor             };                          events.push(newEvent);             calendar.addEvent(newEvent);             renderEvents();                          // 重置表单             eventTitle.value = '';             eventDescription.value = '';         });                  // 渲染事件列表         function renderEvents() {             if (events.length === 0) {                 eventsContainer.innerHTML = '<div>暂无事件,请添加事件</div>';                 return;             }                          eventsContainer.innerHTML = '';                          events.forEach(event => {                 const eventDate = new Date(event.start);                 const eventEl = document.createElement('div');                 eventEl.className = 'event-item';                 eventEl.style.borderLeftColor = event.color;                 eventEl.innerHTML = `                     <div>                         <span>${event.title}</span>                         <span style="color:${event.color}">circle</span>                     </div>                     <div>${eventDate.toLocaleString()}</div>                     <div>${event.description || '无描述'}</div>                 `;                                  eventEl.addEventListener('click', function() {                     if (confirm(`确定要删除 "${event.title}" 事件吗?`)) {                         // 从日历和列表中删除                         calendar.getEventById(event.id).remove();                         events = events.filter(e => e.id !== event.id);                         renderEvents();                     }                 });                                  eventsContainer.appendChild(eventEl);             });         }                  // 初始渲染         renderEvents();     </script> </body> </html>

功能说明

  1. 日历视图

    1. 月、周、日视图切换

    2. 导航按钮(上个月、今天、下个月)

    3. 事件点击可删除

  2. 事件管理

    1. 添加事件(包含标题、描述、颜色)

    2. 事件列表展示

    3. 事件删除功能

  3. 主题切换

    1. 亮色/暗色主题切换

    2. 自动适配日历主题

  4. 响应式设计

    1. 适配不同屏幕尺寸

    2. 移动设备优化

  5. UI 设计

    1. 现代化卡片式设计

    2. 渐变色标题

    3. 直观的图标和按钮

使用方法

  1. 在左侧表单输入事件信息

  2. 选择事件颜色

  3. 点击"添加事件"按钮

  4. 事件将出现在日历和右侧列表中

  5. 点击事件可删除

  6. 使用顶部按钮切换月份

  7. 使用右上角按钮切换主题

这个应用完全使用HTML、CSS和JavaScript实现,不需要任何后端支持,可以直接在浏览器中运行。

联系尚武科技
客户服务
石家庄APP开发
400-666-4864
为您提供售前购买咨询、解决方案推荐等1V1服务!
技术支持及售后
石家庄APP开发公司
0311-66682288
为您提供从产品到服务的全面技术支持 !
客户服务
石家庄小程序开发
石家庄小程序开发公司
加我企业微信
为您提供售前购买咨询、
解决方案推荐等1V1服务!
石家庄网站建设公司
咨询相关问题或预约面谈,可以通过以下方式与我们联系。
石家庄网站制作
在线联系:
石家庄Web开发
石家庄软件开发
石家庄软件开发公司
ADD/地址:
河北·石家庄
新华区西三庄大街86号河北互联网大厦B座二层
Copyright © 2008-2025尚武科技 保留所有权利。 冀ICP备12011207号-2 石家庄网站开发冀公网安备 13010502001294号《互联网平台公约协议》
Copyright © 2025 www.sw-tech.cn, Inc. All rights reserved