mini日历实现
Posted cwxwdm
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mini日历实现相关的知识,希望对你有一定的参考价值。
<!DOCTYPE html>
<html>
<head>
<title></title>
<link href="./index.css" rel="stylesheet" type="text/css"></link>
<script src="./index.js" async></script>
</head>
<body>
<div class="calendar">
<div class="years-group" id="years-group">
<span class="years-item prev-year" id="prev-year"></span>
<span class="years-item current-year"></span>
<span class="years-item next-year" id="next-year"></span>
</div>
<div class="month-switcher">
<span class="month-item prev-month" id="prev-month"></span>
<span class="month-item current-month" id="current-month"></span>
<span class="month-item next-month" id="next-month"></span></span>
</div>
<div class="week-holder">
<span class="week-day">日</span>
<span class="week-day">一</span>
<span class="week-day">二</span>
<span class="week-day">三</span>
<span class="week-day">四</span>
<span class="week-day">五</span>
<span class="week-day">六</span>
</div>
<div class="date-list" id="date-list"></div>
</div>
</body>
</html>
css
/* ------ Reset ------------------------------------------------------- */
*
padding: 0;
margin: 0;
/* ------ Document ---------------------------------------------------- */
html
line-height: 1.15;
font-family: -apple-system, BlinkMacSystemFont, ‘Segoe UI‘, Roboto, Oxygen, Ubuntu, Cantarell, ‘Open Sans‘, ‘Helvetica Neue‘, sans-serif;
font-size: 16px;
color: #7081d6;
-webkit-font-smoothing: antialiased;
/* ------ Element ----------------------------------------------------- */
/* == ------ Calendar ------------------------------------------------- */
.calendar
box-sizing: border-box;
width: 364px;
padding: 12px 14px 20px;
margin: 10px;
border-radius: 5px;
background-color: #0f1a56;
font-weight: bolder;
/* ==== ------ Years-Group -------------------------------------------- */
.years-group
margin-top: 8px;
line-height: 40px;
text-align: center;
.years-item
padding: 0 16px;
vertical-align: baseline;
.prev-year,
.next-year
opacity: .8;
transition: opacity .15s ease-in;
.prev-year:hover,
.next-year:hover
opacity: 1;
cursor: pointer;
.years-group .current-year
font-size: 28px;
/* ==== ------ Month-Switcher ----------------------------------------- */
.month-switcher
margin-bottom: 8px;
line-height: 44px;
text-align: center;
.month-item
display: inline-block;
margin: 8px;
vertical-align: middle;
.prev-month,
.next-month
width: 20px;
height: 20px;
border-radius: 4px;
background-repeat: no-repeat;
background-position: center center;
opacity: .65;
transition: opacity .2s ease-out;
.prev-month
/* background-image: url(‘../../images/icons/arrow-left.png‘); */
background: #1fcda5;
.next-month
/* background-image: url(‘../../images/icons/arrow-right.png‘); */
background: #1fcda5;
.prev-month:hover,
.next-month:hover
background-color: rgba(112, 129, 214, .9);
opacity: .8;
cursor: pointer;
.current-month
padding: 0 10px;
font-size: 18px;
/* ==== ------ Week-Holder ------------------------------------------- */
.week-holder
display: flex;
line-height: 32px;
.week-day
flex: 1;
color: #1fcda5;
text-align: center;
/* ==== ------ Date-List --------------------------------------------- */
.date-list
display: flex;
flex-wrap: wrap;
.date-item
width: 48px;
height: 48px;
line-height: 48px;
font-size: 0;
text-align: center;
.date-badge
display: inline-block;
width: 32px;
height: 32px;
border-radius: 50%;
line-height: 32px;
font-size: 16px;
vertical-align: middle;
transition: all .1s ease-in;
.date-badge:hover
background-color: rgba(27, 42, 116, .8);
cursor: pointer;
.date-list .current-date
position: relative;
width: 28px;
height: 28px;
background-color: rgba(255, 59, 128, .82);
line-height: 28px;
color: rgba(255, 255, 255, .9);
.date-list .current-date::after
content: ‘‘;
position: absolute;
top: -6px;
left: -6px;
width: 28px;
height: 28px;
border: 6px solid rgba(255, 57, 127, .35);
border-radius: 50%;
background-color: transparent;
js
/**
* 获取指定的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();
以上是关于mini日历实现的主要内容,如果未能解决你的问题,请参考以下文章