js实现日期控件

前言

最近花了点时间写了个日期控件,首先说说写日期控件的初衷,有两点:

  • 第一点是没有写过对于日期的生成不甚了解
  • 工作中使用框架的日期控件,但是想要自己实现下

该日期控件主要是学习使用,功能不多,支持输出天以及日期范围的选择。

实现思路

日期控件实现了单日期以及日期范围的功能,单日期实现效果如下图:
单日期选择

日期范围实现效果图如下:
日期范围实现效果图

下面主要说说主要的实现思路,首先说说面板日期的生成,日期面板如下图:
日期面板

日期面板显示是日-六的顺序,首先第一列显示星期日。
日期的生成规则如下:

  • 若生成的当月的第一天是周日则第一行日期都是上个月的
  • 若当月的第一天是周一到周六,则从第一行开始,对应的指定的列

不同的日期控件的生成规则有时会不同,比如win7系统的日期就是我上面的生成规则,win10系统日期生成是周日是最后一列等。

本次日期控件实现主要涉及6个对象,对象说明如下:

SDate:该对象表示日期控件,唯一,对外提供render函数,用于用户配置
Section:区域对象,用于控制整个日期控件的显示与隐藏
Panel:日期对象,表示日期
Nav:区域顶部对象,切换年月的区域
Content:日期内容区域对象
Cell:单元格对象,表示日期的天对应的对应

Cell对象对应的是天,主要的属性如下:

line:行
row:列
value:具体天
isCurrentMonth:是否在当前月
isToday:是否是今天
isActive:是否可被选择
isInRange:是否在选择的日期范围内,多选需要用到
isDisabled:可选范围支持
note:注释信息

Nav对象对应的顶部区域,主要的属性有:

nav:顶部区域节点对象
yearLeftNode:上一年节点对象
yearRightNode:下一年节点对象
monthLeftNode:上一个月节点对象
monthRightNode:下一个月节点对象
yearNode:年显示节点对象
monthNode:月显示节点对象

Content对象的属性如下:

cells:所有cell对象
content:内容区域节点对象

Panel对象的属性如下:

id:唯一标识
initDate:当前面板渲染的时间点
panelNode:dom对象
navArea:Nav对象
contentArea:Content对象

Section对象的属性如下:

status:面板当前显示状态
panels:panel面板对象集合
isRange:是否是日期范围选择
sectionNode:当前section对应的DOM

单纯只考虑日期列表地生成的核心代码如下:

for (let le = 0; le < line; le++) {
	let rows = [];
	for (let rw = 0; rw < row; rw++) {
		// 第一行:处理当月第一天周日与其他的情况
		if (le === 0) {
			dayInWeek === 0 ? 
			(function() {
				rows.push(new Cell(le, rw, 
					daysOfPrevMonth - row + rw + 1, -1));
			}()) : (function() {
				rw < dayInWeek ? rows.push(new Cell(le, rw, daysOfPrevMonth - dayInWeek + rw + 1, -1)) 
				: rows.push(new Cell(le, rw, rw - dayInWeek + 1));
			}());
			// 第二行开始值确定
			if (rw === row - 1) {
				let endValue = rows[rows.length - 1].value;
				lineStart = endValue + 1 > daysOfPrevMonth ? daysOfPrevMonth - endValue : endValue;
			}
		} else  {
			// 其他行
			lineStart += 1;
			if (lineStart <= daysofCurrentMonth) {
				rows.push(new Cell(le, rw, lineStart));
			} else {
				rows.push(new Cell(le, rw, lineStart - daysofCurrentMonth, 1));
			}
		}
	}
结束语

本日期控件目前已重构梳理之前的处理逻辑,代码结构以及结构更加清晰,最新的代码已上传到GitHub上,同时在关键点增加详细注释,新增面板展开动画,修复之前潜在Bug。

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
JSP 中实现日期件,可以使用第三方框架或者自己编写 JavaScript 实现。以下是一个简单的示例代码: 1. 借助第三方框架 使用第三方框架可以简化日期件的实现过程,常见的框架有 jQuery UI、Bootstrap Datepicker 等。以 jQuery UI 为例: 首先,在 jsp 页面中引入 jQuery 库和 jQuery UI 库: ``` <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script> <link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> ``` 然后,在需要使用日期件的 input 标签中添加以下代码: ``` <input type="text" id="datepicker"> ``` 最后,在 JavaScript 中实现日期件: ``` $( function() { $( "#datepicker" ).datepicker(); } ); ``` 2. 自己编写 JavaScript 实现 如果不想使用第三方框架,也可以自己编写 JavaScript 实现。以下是一个简单的示例代码: 在 jsp 页面中添加以下代码: ``` <input type="text" id="datepicker"> ``` 在 JavaScript 中实现日期件: ``` var datepicker = document.getElementById("datepicker"); datepicker.addEventListener("focus", function() { var datePickerDiv = document.createElement("div"); datePickerDiv.setAttribute("id", "datePickerDiv"); var currentDate = new Date(); var currentYear = currentDate.getFullYear(); var currentMonth = currentDate.getMonth() + 1; var currentDay = currentDate.getDate(); var yearSelect = "<select id='yearSelect'>"; for (var i = currentYear - 10; i <= currentYear + 10; i++) { yearSelect += "<option value='" + i + "'>" + i + "</option>"; } yearSelect += "</select>"; var monthSelect = "<select id='monthSelect'>"; for (var i = 1; i <= 12; i++) { var monthText = i < 10 ? "0" + i : i; monthSelect += "<option value='" + i + "'>" + monthText + "</option>"; } monthSelect += "</select>"; var daySelect = "<select id='daySelect'>"; for (var i = 1; i <= 31; i++) { var dayText = i < 10 ? "0" + i : i; daySelect += "<option value='" + i + "'>" + dayText + "</option>"; } daySelect += "</select>"; datePickerDiv.innerHTML = yearSelect + monthSelect + daySelect; datePickerDiv.style.position = "absolute"; datePickerDiv.style.left = datepicker.offsetLeft + "px"; datePickerDiv.style.top = datepicker.offsetTop + datepicker.offsetHeight + "px"; datePickerDiv.style.backgroundColor = "#fff"; datePickerDiv.style.border = "1px solid #ccc"; datePickerDiv.style.padding = "5px"; document.body.appendChild(datePickerDiv); var yearSelect = document.getElementById("yearSelect"); var monthSelect = document.getElementById("monthSelect"); var daySelect = document.getElementById("daySelect"); yearSelect.value = currentYear; monthSelect.value = currentMonth; daySelect.value = currentDay; yearSelect.addEventListener("change", function() { setDays(); }); monthSelect.addEventListener("change", function() { setDays(); }); function setDays() { var year = yearSelect.value; var month = monthSelect.value; var day = daySelect.value; var daysInMonth = new Date(year, month, 0).getDate(); daySelect.innerHTML = ""; for (var i = 1; i <= daysInMonth; i++) { var dayText = i < 10 ? "0" + i : i; daySelect.innerHTML += "<option value='" + i + "'>" + dayText + "</option>"; } if (day > daysInMonth) { daySelect.value = daysInMonth; } else { daySelect.value = day; } } function hideDatePicker() { datePickerDiv.parentNode.removeChild(datePickerDiv); } yearSelect.focus(); yearSelect.select(); yearSelect.addEventListener("blur", function() { hideDatePicker(); }); monthSelect.addEventListener("blur", function() { hideDatePicker(); }); daySelect.addEventListener("blur", function() { hideDatePicker(); }); }); ``` 以上代码实现了一个简单的日期件,包含年、月、日三个下拉框,用户选择日期后会自动填充到 input 标签中。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值