JavaScript实现万年历【展示前后月补充日期、可上下月份切换】

最近在产品业务开展中,碰到了有使用日历展示数据的需求,当即想起来了js常用案例——万年历的实现,这里做的相对简单,只需获取本月的日历展示出来即可,另加上下月份切换。


首先,我们先来看一下最终要实现的效果,即UI设计图:

(这里只讨论万年历展示的实现,业务数据展示已马赛克,请见谅~~)

在设计图中我们可以看出,首尾的灰色部分为上月和下月的相关日期补充,蓝色部分为本月日期展示。 到这里我们就整理一下思路:

1、本月第一天是周几。

2、今年是平年/闰年的判断(关系到二月份天数)。

3、本月第一天前存在多少空位,需要补充多少上月日期。

4、本月最后一天存在多少空位,需要补充多少下月日期。

5、处理好逻辑关系后,将处理完的日历信息进行渲染展示。

思路整理之后,那么我们只需要将我们的逻辑转换为代码:

<!-- 基础布局html(只展示结构,css样式可自行修改,这里不做赘述) -->
<div class="calendarInfo">
	<h6 class="calendarTitle">
		<div class="setImg">				
			<span>工作记录台</span>
			<span id="btn_prevmonth">上一月</span>
			<span id="btn_nextmonth">下一月</span>
		</div>
	</h6>
	<ol>
		<li>周一</li>
		<li>周二</li>
		<li>周三</li>
		<li>周四</li>
		<li>周五</li>
		<li>周六</li>
		<li>周日</li>
	</ol>
	<ul id="calendarInfo">

	</ul>
</div>

对应js处理逻辑:

$(function () {
	let defineDate = new Date();
	let theYear = defineDate.getFullYear(); // 年
	let theMonth = defineDate.getMonth(); // 月
	let theDay = defineDate.getDate(); // 日
	loadchart();
	// 日历信息加载【参数:prev:上月 next:下月】
	function loadchart(prev, next) {
		if (prev != '') { // 上月切换
			if (theMonth == 0) {
				theYear = theYear - 1;
				theMonth = 12;
				theMonth = theMonth - 1;
			} else {
				theMonth = theMonth - 1;
			}
		}
		if (next != '') { // 下月切换
			if (theMonth < 11) {
				theMonth = theMonth + 1;
			} else {
				theMonth = 0;
				theYear = theYear + 1;
			}
		}
		let saveTotalDays = [31, 28 + is_leap(theYear), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; // 包含12个月总天数
		let firstDay = new Date(theYear, theMonth, 1);
		let firstDayWeek = firstDay.getDay(); // 当前月第一天为周几(0-周日,1-周一,以此类推)
		// 判断指定年份是否为闰年(闰年2月为29天/平年2月为28天)
		function is_leap(year) {
			return (year % 100 == 0 ? res = (year % 400 == 0 ? 1 : 0) : res = (year % 4 == 0 ? 1 : 0));
		}
		let momatch = [7, 0, 1, 2, 3, 4, 5]; // 当前月的一号前面有多少空位
		$('#calendarInfo').empty();
		// 处理当前月日历展示
		var calendarInfo = document.getElementById("calendarInfo");
		for (i = parseInt(momatch[firstDayWeek]); i > 0; i--) { // 上月结余
			var preDate = new Date(firstDay - i * 24 * 60 * 60 * 1000).getDate(); //前i天日期【核心】
			calendarInfo.innerHTML += '<li>' + preDate + '</li>';
		}
		var isNowMonth = theMonth + 1, // 当前月份
			isNowYear = theYear; // 当前年份
		$.post(basepath + "xxxx", { // 此接口为业务数据获取,可忽略该请求
			a: 'xxx'
		}, function (data) {
			var preAll = parseInt(saveTotalDays[theMonth] + momatch[firstDayWeek]); //当前月1号前面的空白个数+这个月总天数	
			var j = 0;
			for (i = parseInt(momatch[firstDayWeek] + 1); i <= preAll; i++) {
				if (i == (theDay + momatch[firstDayWeek])) {
					// 判断是否是休班还是工作日	[此处主要展示日期号]
					if (data[j].IsWorkDay == '0') {
						calendarInfo.innerHTML += '<li>' + parseInt(i - momatch[firstDayWeek]) + '</li>';
					} else {
						calendarInfo.innerHTML += '<li>' + parseInt(i - momatch[firstDayWeek]) + '</li>';
					}
				} else { 
					if (data[j].IsWorkDay == '0') {
						calendarInfo.innerHTML += '<li>' + parseInt(i - momatch[firstDayWeek]) + '</li>';
					} else {
						calendarInfo.innerHTML += '<li>' + parseInt(i - momatch[firstDayWeek]) + '</li>';
					}
				}
				j = j + 1;
			}
			let nextMonth = 6 * 7 - preAll; // 需要补充下月展示的数量【6为数据展示6行,7为数据展示7列】
			for (i = 1; i <= nextMonth; i++) { // 下月补充
				calendarInfo.innerHTML += '<li>' + i + '</span></li>';
			}
		}, 'json');
	}
	// 点击上一个月
	$('#btn_prevmonth').click(function () {
		loadchart(true, '');
	});
	// 点击下一个月
	$('#btn_nextmonth').click(function () {
		loadchart('', true);
	});
});
 

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值