利用MomentJS 绘制日历

在这里插入图片描述

前言

  最近因为工作原因,需要按照日历形式展示某功能数据,又遇到前端同事不给力(至于原因嘛,大家都懂得,不在多说),只好自己动手了,毕竟某伟人都说过:自己动手,丰衣足食。废话不多说,先上图耍耍。

在这里插入图片描述

页面源码: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">&nbsp;</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">&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">&nbsp;</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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

独泪了无痕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值