anheyu博客添加侧边栏日历卡片
基于的伍拾柒教程进行修改
i
无需修改主题源文件且代码经过适配
本人大学专业并不与开发相关,仅保证代码可正常运行,不保证其美观性
介绍
博客侧边栏日历组件是一个轻量级的前端组件,用于在网页侧边栏显示当前日期、周数、阳历和农历信息,以及当月的日历网格。该组件支持响应式设计,在不同设备上都能良好显示。
i
该教程的公开版源码未必能有此效果,请自行修改或者参考伍拾柒,本源码仅可用,与本站使用的日历卡片源码毫无关系,因接口写法问题修改了大量代码,与自用接口挂钩导致无法公开使用,请谅解。
效果图

功能介绍
核心功能
- 周数显示:显示当前是当年的第几周和星期几
- 日期显示:大号字体显示当前日期
- 阳历信息:显示当前年份、月份和一年中的第几天
- 农历信息:显示农历年份、月份和日期,包括干支纪年和生肖
- 日历网格:显示当月的日历网格,标记当天日期
- 响应式设计:在移动端设备上自动调整布局和字体大小
- 智能农历转换:优先使用本地农历库,失败时自动切换到API和备用计算方案
技术特点
- 模块化设计:代码采用模块化结构,易于理解和扩展
- 性能优化:DOM元素缓存,避免重复查询
- 容错处理:农历转换失败时自动切换到备用方案
- 响应式布局:使用CSS Grid和媒体查询实现响应式设计
- 样式隔离:使用独立的样式标签,避免与现有样式冲突
- 兼容性良好:支持所有现代浏览器,代码结构清晰易维护
安装方法
方法一:安和鱼博客系统适配
如果你使用的是安和鱼(AnHeYu)博客系统,可以将以下代码添加到后台侧边栏配置中:
配置步骤
- 登录安和鱼博客系统后台(通常为
你的域名/admin) - 进入 系统管理 → 系统设置 → 外观配置 → 侧边栏
- 将以下代码添加到侧边栏配置中
<style>
.calendar-container {
display: flex;
align-items: center;
width: 100%;
padding: 0;
}
.calendar-left {
width: 50%;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
padding-right: 16px;
text-align: center;
min-height: 120px;
justify-content: center;
}
.calendar-week {
font-size: 14px;
font-weight: 600;
margin-bottom: 12px;
width: 100%;
text-align: center;
}
.calendar-date {
font-size: 48px;
font-weight: 700;
color: var(--anzhiyu-main, #1e88e5);
line-height: 1;
margin-bottom: 12px;
}
.calendar-solar {
font-size: 12px;
margin-bottom: 4px;
text-align: center;
}
.calendar-lunar {
font-size: 12px;
color: #a1a2b8;
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.calendar-right {
width: 50%;
display: flex;
flex-direction: column;
}
.calendar-grid {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 4px;
width: 100%;
}
.calendar-day {
aspect-ratio: 1;
display: flex;
align-items: center;
justify-content: center;
font-size: clamp(8px, 2vw, 12.7px);
border-radius: 50%;
transition: all 0.2s ease;
width: 100%;
max-width: 40px;
margin: 0 auto;
}
.calendar-day a {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
border-radius: 50%;
text-decoration: none;
font-size: inherit;
}
.calendar-day a:hover {
background-color: rgba(30, 136, 229, 0.1);
}
.calendar-day a.now {
background-color: var(--anzhiyu-main, #1e88e5);
color: white;
font-weight: 600;
}
.calendar-day.other-month a {
color: #ccc;
}
@media (max-width: 768px) {
.calendar-container {
padding: 0;
flex-direction: column;
}
.calendar-left {
width: 100%;
padding-right: 0;
margin-bottom: 16px;
}
.calendar-right {
width: 100%;
}
.calendar-date {
font-size: 36px;
}
.calendar-day {
max-width: 36px;
}
}
@media (max-width: 480px) {
.calendar-date {
font-size: 28px;
}
.calendar-day {
max-width: 32px;
font-size: clamp(6px, 2vw, 10px);
}
.calendar-grid {
gap: 2px;
}
}
</style>
<div class="calendar-container">
<div class="calendar-left">
<div class="calendar-week" id="calendar-week"></div>
<div class="calendar-date" id="calendar-date"></div>
<div class="calendar-solar" id="calendar-solar"></div>
<div class="calendar-lunar" id="calendar-lunar"></div>
</div>
<div class="calendar-right">
<div class="calendar-grid" id="calendar-main"></div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/chinese-lunar@0.1.4/lib/chinese-lunar.js" defer></script>
<script>
(function() {
'use strict';
const now = new Date();
let calendarElements = null;
function getLunarFromAPI() {
return new Promise((resolve, reject) => {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 3000);
fetch('https://api.lolimi.cn/API/rl/api?type=json', {
signal: controller.signal
})
.then(response => {
clearTimeout(timeoutId);
if (!response.ok) {
throw new Error('API request failed');
}
return response.json();
})
.then(data => {
if (data.code === 1 && data.data) {
resolve(data.data);
} else {
reject(new Error('Invalid API response'));
}
})
.catch(() => {
clearTimeout(timeoutId);
reject(new Error('API request failed'));
});
});
}
function getSimpleLunarDate(year, month, date) {
const lunarMonths = ['正月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '冬月', '腊月'];
const lunarDays = ['初一', '初二', '初三', '初四', '初五', '初六', '初七', '初八', '初九', '初十', '十一', '十二', '十三', '十四', '十五', '十六', '十七', '十八', '十九', '二十', '廿一', '廿二', '廿三', '廿四', '廿五', '廿六', '廿七', '廿八', '廿九', '三十'];
const monthIndex = month;
const dayIndex = date - 1;
return {
month: lunarMonths[monthIndex] || '正月',
day: lunarDays[dayIndex] || '初一'
};
}
function cacheElements() {
if (!calendarElements) {
calendarElements = {
container: document.querySelector('.calendar-container'),
week: document.getElementById('calendar-week'),
date: document.getElementById('calendar-date'),
solar: document.getElementById('calendar-solar'),
lunar: document.getElementById('calendar-lunar'),
main: document.getElementById('calendar-main')
};
}
return calendarElements;
}
function generateCalendarDays(year, month, date, daysInMonth, startDay) {
const elements = cacheElements();
if (!elements.main) return;
elements.main.innerHTML = '';
const weeksNeeded = Math.ceil((daysInMonth + startDay) / 7);
let currentDay = '';
let isCurrentMonth = false;
for (let week = 0; week < weeksNeeded; week++) {
for (let day = 0; day < 7; day++) {
if (week === 0 && day === startDay) {
currentDay = 1;
isCurrentMonth = true;
}
const dayEl = document.createElement('div');
dayEl.className = 'calendar-day';
if (currentDay === '' || currentDay > daysInMonth) {
dayEl.classList.add('other-month');
}
const isToday = currentDay === date;
const nowClass = isToday ? " class='now'" : "";
dayEl.innerHTML = `<a${nowClass}>${currentDay}</a>`;
elements.main.appendChild(dayEl);
if (currentDay >= daysInMonth) {
currentDay = '';
isCurrentMonth = false;
}
if (isCurrentMonth) {
currentDay += 1;
}
}
}
}
function calculateWeekNumber() {
const startOfYear = new Date(now.getFullYear(), 0, 1);
const dayOfYear = Math.floor((now - startOfYear) / (1000 * 60 * 60 * 24));
const dayOfWeek = now.getDay();
return dayOfWeek - (dayOfYear % 7) >= 0 ? Math.ceil(dayOfYear / 7) : Math.ceil(dayOfYear / 7) + 1;
}
function updateCalendarDisplay() {
const elements = cacheElements();
if (!elements.container) return;
const year = now.getFullYear();
const month = now.getMonth();
const date = now.getDate();
const dayOfWeek = now.getDay();
const isLeapYear = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
const weekNames = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"];
const monthData = [
{ month: "1月", days: 31 },
{ month: "2月", days: isLeapYear ? 29 : 28 },
{ month: "3月", days: 31 },
{ month: "4月", days: 30 },
{ month: "5月", days: 31 },
{ month: "6月", days: 30 },
{ month: "7月", days: 31 },
{ month: "8月", days: 31 },
{ month: "9月", days: 30 },
{ month: "10月", days: 31 },
{ month: "11月", days: 30 },
{ month: "12月", days: 31 },
];
const currentMonth = monthData[month];
const monthName = currentMonth.month;
const daysInMonth = currentMonth.days;
const firstDayOfMonth = new Date(year, month, 1);
const startDay = firstDayOfMonth.getDay();
generateCalendarDays(year, month, date, daysInMonth, startDay);
const weekNumber = calculateWeekNumber();
if (elements.week) elements.week.innerHTML = `第${weekNumber}周 ${weekNames[dayOfWeek]}`;
if (elements.date) elements.date.innerHTML = date.toString().padStart(2, "0");
const startOfYear = new Date(year, 0, 1);
const dayOfYear = Math.floor((now - startOfYear) / (1000 * 60 * 60 * 24)) + 1;
if (elements.solar) elements.solar.innerHTML = `${year}年${monthName} 第${dayOfYear}天`;
if (elements.lunar) {
updateLunarDisplay(year, month, date, elements.lunar);
}
}
function updateLunarDisplay(year, month, date, lunarEl) {
if (typeof chineseLunar !== 'undefined' && chineseLunar) {
try {
const lunarDate = chineseLunar.solarToLunar(new Date(year, month, date));
const animalYear = chineseLunar.format(lunarDate, "A");
const ganzhiYear = chineseLunar.format(lunarDate, "T").slice(0, -1);
const lunarMon = chineseLunar.format(lunarDate, "M");
const lunarDay = chineseLunar.format(lunarDate, "d");
const lunarText = `${ganzhiYear}${animalYear}年 ${lunarMon}${lunarDay}`;
lunarEl.innerHTML = lunarText;
return;
} catch (e) {
}
}
fallbackToAPI(lunarEl);
}
function fallbackToAPI(lunarEl) {
getLunarFromAPI().then(data => {
if (data && data.lunar) {
lunarEl.innerHTML = data.lunar;
} else {
fallbackToSimpleCalculation(lunarEl);
}
}).catch(() => {
fallbackToSimpleCalculation(lunarEl);
});
}
function fallbackToSimpleCalculation(lunarEl) {
const year = now.getFullYear();
const month = now.getMonth();
const date = now.getDate();
const simpleLunar = getSimpleLunarDate(year, month, date);
lunarEl.innerHTML = `${year}年 ${simpleLunar.month}${simpleLunar.day}`;
}
function initializeCalendar() {
try {
updateCalendarDisplay();
} catch (e) {
updateCalendarDisplay();
}
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initializeCalendar);
} else {
initializeCalendar();
}
if (window.addEventListener) {
window.addEventListener('pjax:complete', initializeCalendar);
}
window.initializeCalendar = initializeCalendar;
})();
</script>
方法二:外部引入
将代码保存为 calendar.js 文件,然后在HTML中引入:
<link rel="stylesheet" href="path/to/calendar.css"> <div class="calendar-container"> <!-- 日历HTML结构 --> </div> <script src="https://cdn.jsdelivr.net/npm/chinese-lunar@0.1.4/lib/chinese-lunar.js" defer></script> <script src="path/to/calendar.js"></script>
自定义配置
日历组件的样式和行为可以通过修改CSS和JavaScript来调整:
配置项说明
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| --anzhiyu-main | CSS变量 | #1e88e5 | 主题主色调,用于日期和当天标记 |
| calendar-date | CSS类 | font-size: 48px | 当前日期字体大小 |
| calendar-grid | CSS类 | grid-template-columns: repeat(7, 1fr) | 日历网格布局 |
| MOBILE_WIDTH | 媒体查询 | 768px | 判定为移动端的宽度阈值 |
修改主题颜色
如果你想修改日历的主题颜色,可以调整CSS变量:
:root {
--anzhiyu-main: #ff4500; /* 修改为你想要的颜色 */
}
修改字体大小
如果你想调整日期显示的字体大小,可以修改CSS:
.calendar-date {
font-size: 40px; /* 修改为你想要的大小 */
/* 其他样式... */
}
实现原理
核心功能
- DOM元素缓存:使用缓存机制避免重复查询DOM元素,提升性能
- 周数计算:根据当前日期计算当年的周数
- 日历网格生成:根据当月天数和起始星期几生成日历网格
- 农历转换:优先使用本地农历库,失败时自动切换到API和备用计算方案
- 响应式布局:使用CSS Grid和媒体查询实现响应式设计
代码结构
:::folding open 代码结构解析
- 全局变量:定义当前日期和DOM元素缓存
- 农历获取:提供API和备用计算方案
- DOM操作:缓存和生成日历元素
- 日历生成:计算并生成日历网格
- 周数计算:计算当年的周数
- 显示更新:更新日历各部分的显示内容
- 农历显示:处理农历信息的显示
- 初始化函数:初始化日历组件
- 事件监听:支持DOM加载和Pjax :::
注意事项
使用注意事项
- 兼容性:该组件使用了现代JavaScript语法,在IE浏览器上可能无法正常工作
- 性能:在低配置设备上,农历API请求可能会影响性能
- 依赖:依赖外部农历库和API,网络不稳定时可能会影响农历显示
- 样式冲突:如果你的网站使用了相同的CSS类名,可能会产生样式冲突
- 移动端:在宽度小于768px的设备上,日历布局会自动调整
常见问题
Q: 日历不显示怎么办?
A: 请检查以下几点:
- 确认代码是否正确复制到HTML文件中
- 检查浏览器控制台是否有错误信息
- 确认网络连接正常,能够加载农历库和API
Q: 农历信息显示不正确怎么办?
A: 农历转换使用了多级备用方案:
- 首先尝试使用本地农历库
- 失败时尝试使用API
- 最后使用备用计算方案
如果所有方案都失败,可能是网络问题或农历库加载失败。
Q: 如何修改日历的大小?
A: 可以修改CSS中的相关样式:
.calendar-container {
width: 100%; /* 修改为你想要的宽度 */
/* 其他样式... */
}
.calendar-date {
font-size: 48px; /* 修改为你想要的大小 */
/* 其他样式... */
}
总结
博客侧边栏日历组件是一个功能丰富、易于使用的前端组件,可以为你的网站增添实用的日期显示功能。它具有以下特点:
- ✅ 功能完整,显示周数、日期、阳历和农历信息
- ✅ 响应式设计,自动适配不同设备
- ✅ 智能农历转换,多级备用方案确保显示稳定
- ✅ 轻量级实现,加载速度快
- ✅ 可自定义,支持修改颜色、字体大小等样式
希望这个教程对你有所帮助,祝你使用愉快!
📞 联系方式
如有问题或建议,欢迎在评论区交流或联系我: 发送邮件 📧
本教程基于anheyu-app主题开发,无需修改主题源文件且代码经过适配 其他博客系统可能需要适当调整。 代码已优化,兼容大部分现代浏览器。

评论区
评论加载中...