-
该日历主要是提供一个思路,用以抛砖引玉
-
该日历从移动端更改而来,所以看着会比较小
-
日历中基于
flex
布局,全部使用div
模拟table
来实现,没有用table
来布局 -
日历的周次列是固定的,这是基于自己需求来设定的,如果有别的需求,可以按需修改
-
css 代码
.school-calendar { display: flex; flex-flow: column nowrap; width: 375px; height: 600px; } .school-calendar .calendar-table { background-color: #fff; flex: auto; overflow-y: auto; } .school-calendar .calendar-table .thead { background-color: #f1f3f6; color: #666; position: sticky; line-height: 35px; top: 0; } .school-calendar .calendar-table .thead .tr { display: flex; flex-flow: row wrap; } .school-calendar .calendar-table .thead .tr>div { padding: 5px 0; height: 45px; text-align: center; border-bottom: 1px solid #d9dce0; width: calc((100% - 51px) / 7); } .school-calendar .calendar-table .thead .tr>div:first-child { width: 51px; } .school-calendar .calendar-table .tbody .tr { display: flex; flex-flow: row wrap; } .school-calendar .calendar-table .tbody .tr .week-num, .school-calendar .calendar-table .tbody .tr .week-list>div { padding: 5px 0; height: 45px; text-align: center; border-bottom: 1px solid #d9dce0; width: calc(100% / 7); box-sizing: border-box; } .school-calendar .calendar-table .tbody .tr .week-num { width: 51px; background-color: #f1f3f6; color: #666; line-height: 35px; } .school-calendar .calendar-table .tbody .tr .week-list { display: flex; flex-flow: row wrap; width: calc(100% - 51px); } .school-calendar .calendar-table .tbody .tr .week-list>div { border-left: 1px solid #d9dce0; } .school-calendar .calendar-table .tbody .tr .week-list>div>p.today { color: #fff; background-color: #1574df; padding: 4px; border-radius: 4px; margin-top: -4px; } .school-calendar .calendar-table .tbody .tr:last-child>.week-num, .school-calendar .calendar-table .tbody .tr:last-child>.week-list>div { border-bottom: none; }
-
html 代码
<div class="school-calendar"> <div class="calendar-table"> <div class="thead"> <div class="tr"> <div>周</div> <div>日</div> <div>一</div> <div>二</div> <div>三</div> <div>四</div> <div>五</div> <div>六</div> </div> </div> <div class="tbody"> </div> </div> </div>
-
javascript 代码
/* 格式化时间 */ function dateFormat(date, fmt) { const o = { 'M+': date.getMonth() + 1, // 月份 'd+': date.getDate(), // 日 'h+': date.getHours() % 12 === 0 ? 12 : date.getHours() % 12, // 小时 'H+': date.getHours(), // 小时 'm+': date.getMinutes(), // 分 's+': date.getSeconds(), // 秒 'q+': Math.floor((date.getMonth() + 3) / 3), // 季度 'S': date.getMilliseconds() // 毫秒 } const week = { '0': '日', '1': '一', '2': '二', '3': '三', '4': '四', '5': '五', '6': '六' } if (/(y+)/.test(fmt)) { fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length)); } if (/(E+)/.test(fmt)) { fmt = fmt.replace(RegExp.$1, ((RegExp.$1.length > 1) ? (RegExp.$1.length > 2 ? '星期' : '周') : '') + week[date.getDay() + '']); } for (const k in o) { if (new RegExp('(' + k + ')').test(fmt)) { fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length))); } } return fmt } /* 返回开始时间与结束时间中的每一天 */ function formatEveryDay(startDate, endDate, showYear, fmt) { showYear = showYear === undefined ? true : showYear fmt = fmt === undefined ? (showYear ? 'yyyy-MM-dd' : 'MM-dd') : fmt const dateList = [] const startTime = new Date(startDate) const endTime = new Date(endDate) while ((endTime.getTime() - startTime.getTime()) >= 0) { dateList.push(dateFormat(startTime, fmt)) startTime.setDate(startTime.getDate() + 1) } return dateList } /* 获取该日期的详细数据 */ function getDayInfoByDate(date, startDate, endDate) { const dayObj = {} if (date) { const dateTime = new Date(date) const day = dateTime.getDate() const isStartDay = date === startDate const dayArr = date.split('-') const lastDayOfMonth = dayArr.length === 3 ? new Date(dayArr[0], dayArr[1], 0).getDate() : false const isLastDayOfMonth = lastDayOfMonth === day // 即是本月的第一天又是本月的最后一天 const isNewMonth = day === 1 || isStartDay dayObj['dateText'] = date // 年-月-日 dayObj['day'] = day // 当前属于该月的第几天 dayObj['dayText'] = isNewMonth ? dateTime.getMonth() + 1 + '月' + (isLastDayOfMonth ? day : '') : day // 日历中具体显示的文本 dayObj['newMonth'] = isNewMonth // 是否属于新的一个月 dayObj['startDay'] = isStartDay // 是否是该时间段的开始时间 dayObj['week'] = dateTime.getDay() // 当前属于星期几,周日是0,周一是1 } return dayObj } const startDate = '2022-12-31' //日历开始时间 const endDate = '2023-08-23' //日历结束时间 const today = dateFormat(new Date(), 'yyyy-MM-dd') const days = formatEveryDay(startDate, endDate) // 开始时间与结束时间之间的每一天 const weeks = [] // 存储所有周 let tempWeeks = [] days.forEach(day => { const dayInfo = this.getDayInfoByDate(day, startDate, endDate) if (dayInfo.newMonth) { // 学期开始与月的第一天是周日的情况下不需要填充空格 const dayNum = dayInfo.startDay || (dayInfo.newMonth && dayInfo.week === 0) ? dayInfo.week : 7 for (let j = 0; j < dayNum; j++) { tempWeeks.push(this.getDayInfoByDate()) } } tempWeeks.push(dayInfo) if (dayInfo.week === 6) { weeks.push(tempWeeks) tempWeeks = [] } }) let domStr = '' weeks.forEach((week, index) => { let dayEl = '' week.forEach(dayObj => { dayEl += ` <div> ${dayObj.dateText === today ? '<p class="today">今</p>' : (dayObj.dayText ? dayObj.dayText : '')} </div>` }) domStr += ` <div class="tr"> <div style="${week.length > 7 ? 'height: 90px;line-height: 80px;' : ''}" class="week-num"> ${index + 1} </div> <div class="week-list"> ${dayEl} </div> </div>` }) document.querySelector('.tbody').innerHTML = domStr