/**
* 获取指定的DOM元素
* @param {string} selector
* @return {object} 单个元素或元素集合
*/
function $(selector) {
if (/^#/.test(selector)) {
return document.querySelector(selector);
}
return document.querySelectorAll(selector);
}
/**
* 将类数组转换为真实数组
* @param {NodeList} likeArray
* @return {array} 真实数组
*/
function toArray(likeArray) {
return Array.prototype.slice.call(likeArray);
}
/**
* 初始化日历
*/
function CalendarInit() {
const date = new Date();
const realYear = date.getFullYear();
const realMonth = date.getMonth() + 1;
const realDay = date.getDate();
const dateList = $(‘#date-list‘);
const currentMonthTextContainer = $(‘#current-month‘);
let currentYear = realYear; // 当前年份
let currentMonth = realMonth; // 当前月份
// 判断是否为闰年
const isLeapYear = (() => {
if (
currentMonth % 400 === 0
|| (currentMonth % 4 === 0 && currentMonth % 100 !== 0)
) {
return true;
}
return false;
})();
// 获取年份单元
const getYearsGroup = (yearNumber) => {
return [yearNumber - 1, yearNumber, yearNumber + 1];
};
// 展示年份单元
const renderYearsGroup = (yearsArray) => {
const yearNodeList = toArray($(‘.years-item‘));
yearsArray.forEach((year, index) => {
yearNodeList[index].innerHTML = year;
});
};
// 切换到上一年
const toPrevYear = () => {
currentYear -= 1;
renderYearsGroup(getYearsGroup(currentYear));
};
// 切换到下一年
const toNextYear = () => {
currentYear += 1;
renderYearsGroup(getYearsGroup(currentYear));
};
// 获取转化后的汉字月份
const getMonthChineseText = (monthNumber) => {
switch (monthNumber) {
case 1:
return ‘一月‘;
case 2:
return ‘二月‘;
case 3:
return ‘三月‘;
case 4:
return ‘四月‘;
case 5:
return ‘五月‘;
case 6:
return ‘六月‘;
case 7:
return ‘七月‘;
case 8:
return ‘八月‘;
case 9:
return ‘九月‘;
case 10:
return ‘十月‘;
case 11:
return ‘十一月‘;
case 12:
return ‘十二月‘;
default:
return ‘‘;
}
};
// 渲染当前月份
const renderCurrentMonthText = (monthNumber) => {
currentMonthTextContainer.innerHTML = getMonthChineseText(monthNumber);
};
// 获取指定月份的天数
const getCurrentMonthDays = (monthNumber) => {
switch (monthNumber) {
case 1:
return 31;
case 2:
return isLeapYear ? 29 : 28;
case 3:
return 31;
case 4:
return 30;
case 5:
return 31;
case 6:
return 30;
case 7:
return 31;
case 8:
return 31;
case 9:
return 30;
case 10:
return 31;
case 11:
return 30;
case 12:
return 31;
default:
return 0;
}
};
// 获取某月的第一天是星期几
const getWeekDayNumberOnTheFirstDayOfCurrentMonth = () => {
const month = currentMonth > 9 ? currentMonth : (‘0‘ + currentMonth);
const firstDay = `${currentYear}-${month}-01`;
return (new Date(firstDay)).getDay();
};
// 生成日历单元的html字符串
const generateItemHtmlString = (dayNumber, classDecorator = ‘‘) => {
if (classDecorator) {
classDecorator = ` ${classDecorator}`;
}
return `
<div class="date-item">
<span class="date-badge${classDecorator}">${dayNumber}</span>
</div>
`;
};
// 渲染日历
const renderCalendarItems = () => {
const currentMonthWholeDays = getCurrentMonthDays(currentMonth);
const startDay = getWeekDayNumberOnTheFirstDayOfCurrentMonth();
const currentDayClassName = ‘current-date‘;
let templateString = ‘‘;
let dayMark = 0;
for (let i = 0; i < currentMonthWholeDays + startDay; i++) {
dayMark = i + 1 - startDay;
if (
currentYear === realYear
&& currentMonth === realMonth
&& dayMark === realDay
) {
templateString += generateItemHtmlString(dayMark, currentDayClassName);
continue;
}
if (i >= startDay) {
templateString += generateItemHtmlString(dayMark);
continue;
}
// 补空
templateString += ‘<div class="date-item"></div>‘;
}
dateList.innerHTML = templateString;
};
// 处理年份变化
const handleYearControllerChange = () => {
const prevYear = $(‘#prev-year‘);
const nextYear = $(‘#next-year‘);
prevYear.addEventListener(‘click‘, () => {
toPrevYear();
renderCalendarItems();
});
nextYear.addEventListener(‘click‘, () => {
toNextYear();
renderCalendarItems();
});
};
// 处理月份变化
const handleMonthControllerChange = () => {
const prevMonth = $(‘#prev-month‘);
const nextMonth = $(‘#next-month‘);
prevMonth.addEventListener(‘click‘, () => {
if (currentMonth === 1) {
toPrevYear();
currentMonth = 12;
} else {
currentMonth -= 1;
}
renderCurrentMonthText(currentMonth);
renderCalendarItems();
});
nextMonth.addEventListener(‘click‘, () => {
if (currentMonth === 12) {
toNextYear();
currentMonth = 1;
} else {
currentMonth += 1;
}
renderCurrentMonthText(currentMonth);
renderCalendarItems();
});
};
renderYearsGroup(getYearsGroup(currentYear));
renderCurrentMonthText(currentMonth);
renderCalendarItems();
handleYearControllerChange();
handleMonthControllerChange();
}
CalendarInit();