前言
最近因为工作原因,需要按照日历形式展示某功能数据,又遇到前端同事不给力(至于原因嘛,大家都懂得,不在多说),只好自己动手了,毕竟某伟人都说过:自己动手,丰衣足食。废话不多说,先上图耍耍。
页面源码:moment.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js" type="text/javascript" charset="utf-8"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment-with-locales.min.js" type="text/javascript" charset="utf-8"></script>
<title>利用MomentJS 绘制日历</title>
<script type="text/javascript">
</script>
</head>
<body>
<button id="preyear">前一年</button>
<strong><input id="year" type="text" name="year" readonly><span>年</span></strong>
<button id="nextyear">下一年</button>
<div class="schedule-wrap">
<div id="schedule-content" style="display:inline-block;width:88%;"></div>
</div>
<div style="display:none">
<input name="includeYears" id="includeYears" type="hidden" value="" />
</div>
</body>
<script src="calendar.js" type="text/javascript" charset="utf-8"></script>
<link rel="stylesheet" type="text/css" href="calendar.css"/>
</html>
样式源码:calendar.css
.schedule-wrap{
text-align: justify;
margin-bottom: 10px;
margin-top: 20px;
line-height: 0;
background: #FCFCFC;
position: relative;
top: -1px;
}
.schedule-calendar{
width: 23%;
background: #EFEFEF;
padding: 4px;
display: inline-block;
vertical-align: top;
margin: 10px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.schedule-calendar-fixed{
width: 250px;
display: inline-block;
vertical-align: top;
margin-left: 10px;
margin-right: 10px;
padding-left: 4px;
padding-right: 4px;
}
.schedule-calendar-container,
.schedule-calendar-week-head,
.schedule-calendar-week-head td,
.schedule-calendar-days,
.schedule-calendar-days td,
.schedule-calendar-header {
margin: 0;
padding: 0;
font-size: 12px;
line-height: 13px;
cursor: default;
text-shadow: none !important;
}
.schedule-calendar-container {
position: relative;
background: #FFF;
}
.schedule-calendar-container table {
width: 100%;
border: 0;
border-collapse: collapse !important;
border-spacing: 0 !important;
}
.schedule-calendar-month {
padding-top: 6px;
padding-bottom: 6px;
text-align: center;
border: 1px solid #EBEBEB;
border-bottom-width: 0px;
color: #757575;
font-size: large;
}
.schedule-calendar-week-head td {
width: 14%;
vertical-align: top;
text-align: center;
padding: 10px 0 8px;
border: 1px solid #EBEBEB;
color: #B5B5B5;
font-size: 12px;
line-height: 1.333;
text-transform: uppercase;
}
.schedule-calendar-days{
margin-top: -1px;
}
.schedule-calendar-days td {
width: 14%;
vertical-align: top;
text-align: center;
padding: 10px 0 8px;
border: 1px solid #EBEBEB;
color: #757575;
font-size: 12px;
line-height: 1.333;
text-transform: uppercase;
}
.schedule-calendar-days .schedule-calendar-day{
cursor: pointer;
}
.schedule-calendar-days .schedule-calendar-day-empty {
background: #FFF url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAMAAAC6sdbXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAAZQTFRF7u7uKNOqmgAAABlJREFUeNpiYGRkZABCCGIA8UAEI4QACDAAAUoAFV5+ydgAAAAASUVORK5CYII=');
}
Js源码:
$(function() {
// 当前日历年份
var currentYear = moment().year();
$("#year").val(currentYear);
/**
* 调用初始化函数
*/
initSchedule(initCalendarByYear(currentYear));
/**
* 查看下一年工作日历状态
* @param unid
* @returns
*/
$("#nextyear").on("click", function() {
switchYearCalendar("next");
});
/**
* 查看前一年工作日历
*/
$("#preyear").on("click", function() {
switchYearCalendar("pre");
});
});
/**
* 初始化工作日历
*/
var initSchedule = function(calendarInfo) {
$("#schedule-content").html("");
moment.locale((navigator.userLanguage || navigator.language).toLowerCase());
var MONTHS = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
var curYear = $('#year') && $('#year').val() || moment().year();
var monthsData = {};
$.each(calendarInfo, function(index, item) {
var month = item.month;
var dateStr = item.year + "-" + (month < 10 ? "0" + month : month) + "-" + (item.day < 10 ? "0" + item.day :
item.day);
var monthStr = "" + (item.month);
if (!monthsData[monthStr]) {
monthsData[monthStr] = {};
}
monthsData[monthStr][dateStr] = item;
})
$.each(MONTHS, function(index, curMonth) {
$("#schedule-content").append('<span style="display: inline-block;" class="schedule-calendar" id="calendar_' +
curMonth + '"></span>');
var monthStr = "" + curMonth;
var calendar = new Calendar('calendar_' + curMonth, [curYear, curMonth - 1], monthsData[monthStr]);
});
$.each(_typeColor, function(index, item) {
$("[data-type='" + index + "']").css("background-color", item["background-color"]);
$(".schedule-calendar-days .schedule-calendar-day[data-type='" + index + "']").css("color", item["color"]);
})
for (var i = 0; i < MONTHS.length; i++) {
$("#schedule-content").append('<div class="schedule-calendar-fixed"></div> ');
}
};
/**
* 绘制日期
* @param {Object} target
* @param {Object} date
* @param {Object} monthData
*/
var Calendar = function(target, date, monthData) {
var theMonthData = monthData;
if (typeof target === 'string') {
target = $("#" + target);
}
var timeForWork, weekFirstDay, weekLastDay, monthLastDay, html;
var prepareCalendar = function() {
timeForWork = moment(date);
weekFirstDay = parseInt(timeForWork.startOf("month").format("d"));
weekLastDay = parseInt(timeForWork.endOf("month").format("d"));
monthLastDay = parseInt(timeForWork.endOf("month").format("D"));
html = '<div class="schedule-calendar-container">';
// 顶部月份
html += '<div class="schedule-calendar-header">';
html += '<div class="schedule-calendar-month">';
html += timeForWork.format("MMMM");
html += '</div>';
// 星期
html += '<table class="schedule-calendar-week-head"><tr>';
for (i = 0; i < 7; i++) {
html += '<td>' + timeForWork.day(i).format("dd") + '</td>';
}
html += '</tr></table>';
// 日期
html += '<table class="schedule-calendar-days"><tr>';
// 上个月
for (i = 0; i < weekFirstDay; i++) {
html += '<td class="schedule-calendar-day-empty"> </td>';
}
// 本月的日期
var curDate = moment(date).startOf("month");
var dateFormat;
for (i = 1; i <= monthLastDay; i++) {
dateFormat = curDate.format('YYYY-MM-DD');
var type = theMonthData[dateFormat].timeCode;
var note = "";
var noteClass = (note && note !== '') ? 'has-note' : '';
var bullNode = (note && note !== '') ? '<i class="bull">•</i>' : '';
html += '<td class="schedule-calendar-day" data-date="' + dateFormat + '" data-type="' + type + '">' +
'<div class="' + noteClass + '">' + i + bullNode + '</div>' + '</td>';
// 新的一周要换行
if ((weekFirstDay + i) / 7 === Math.floor((weekFirstDay + i) / 7)) {
html += '</tr><tr>';
}
curDate.add(1, 'days');
}
// 下个月
for (i = weekLastDay; i < 6; i++) {
html += '<td class="schedule-calendar-day-empty"> </td>';
}
html += '</tr></table>';
placeCalendar();
};
var placeCalendar = function() {
$(target).append(html);
$(target).delegate('[data-date]', 'click', function() {
var dataType = $(this).attr('data-type');
var dataDate = moment($(this).attr('data-date'));
var item = theMonthData[dataDate.format('YYYY-MM-DD')];
});
};
prepareCalendar();
return this;
}
var _typeColor = {
"_sys_workday": {
"background-color": "",
"color": "#757575",
"name": "工作日"
},
"_sys_weekend": {
"background-color": "#1abc9c",
"color": "#FFF",
"name": "休息日"
},
"_sys_statutory": {
"background-color": "#3498db",
"color": "#FFF",
"name": "法定假日"
}
}
/**
* 切换不同年的工作日历
* @returns
*/
var switchYearCalendar = function(opt) {
var curyear = "";
if (opt == "pre") {
curyear = parseInt($("#year").val()) - 1;
} else if (opt == "next") {
curyear = parseInt($("#year").val()) + 1;
}
$("#year").val(curyear);
initSchedule(initCalendarByYear(curyear));
}
/**
* 获取某一年的所有日期数据
* @param {Object} year
*/
var initCalendarByYear = function(year) {
// 创建星期数组
var today = new Array("日", "一", "二", "三", "四", "五", "六");
var monthday = [];
var items = [];
if (isLeapYear(year)) {
monthDayArr = new Array(31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
} else {
monthDayArr = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
}
for (var month = 1; month < 13; month++) {
var endday = monthDayArr[month - 1];
for (var dayNum = 1; dayNum <= endday; dayNum++) {
var day = new Date(year + "-" + month + "-" + dayNum).getDay();
var item = {};
item.calendarCode = null;
item.day = dayNum;
item.month = month;
if (day == 0 || day == 6) {
item.timeCode = "_sys_weekend";
item.color = "#1abc9c";
} else {
item.timeCode = "_sys_workday";
item.color = "";
}
item.calendarCode = "星期" + today[day];
item.year = year;
items.push(item);
}
}
return items;
}
/**
* 是否是闰年
*
* @param {Object} year
*/
var isLeapYear = function(year) {
if (year % 4 != 0 || (year % 100 == 0 && year % 400 != 0)) {
return false;
}
return true;
}