DIY一个JS年月calendar

本文分享了一个使用jQuery实现的自定义年月选择器的开发过程。该选择器旨在解决仅需选择年月的需求,通过点击输入框弹出包含年份下拉列表及月份表格的选择界面。

写一个项目,遇到需求:只输入年月。我在网上找不半天的JS控件,无果。TX哥们让我自已写个,好吧。那就写试试。

不要紧,一写就是两天。居然都没成功。晕。。。。。。上代码。下面。

 

 

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>MyCalendar</title>
	<script type="text/javascript" src="jquery-1.6.min.js"></script>
	<script type="text/javascript">
		$(function(){
		
			function YMCal(obj){
				this.output_ym="";
				this.cur_year=new Date().getFullYear();
				this.start_year=1936;
				this.sl_year=0;
				this.sl_month=12;
				this.init=function(){
					for(var i=this.start_year;i<=this.cur_year;i++){
							$("<option value='"+i+"年'>"+i+"年</option>").appendTo("#ym_year");
						}
						if(obj.val()!=null&&obj.val()!=""){
							this.sl_year=obj.val().substr(0,4);
							this.sl_month=obj.val().substring(5,obj.val().length-1);
						}else{
							this.sl_year=this.cur_year-24;
						}
						$("#ym_month table tr td").removeClass("m_select");
						$("#ym_month table tr td:eq("+(this.sl_month-1)+")").addClass("m_select");
						$("#ym_year option[value='"+this.sl_year+"年']").attr("selected", true);
						$("#ym_calendar").css("margin-left",obj.position().left-6);
						$("#ym_calendar").show();
						$("#ym_calendar").insertAfter(obj);
						
						$("#ym_month table tr td").hover(function(){
							$(this).addClass("focus");
						},function(){
							$(this).removeClass("focus");
						}).click(function(){
							this.sl_month=$(this).text();
							this.sl_year=$("#ym_year").find("option:selected").text();
							this.output_ym=this.sl_year+this.sl_month;
							obj.val(this.output_ym);
							$("#ym_calendar").hide();
					});
					obj.blur(function(){
						$("#ym_calendar").hide();
					});
				};
			}
			
			
			$("#myCalendar").click(function(){
				var ymCal= new YMCal($(this));
				ymCal.init();
			});
			$("#myCalendar2").click(function(){
				var ymCal= new YMCal($(this));
				ymCal.init();
			});
		});
	</script>
	<style type="text/css">
	#ym_calendar {
		z-index: 99;
		position: absolute;
		width: 170px;
		color: black;
		border: #A9A9FF 1px solid;
		background: white;
		padding: 1px;
	}
	#ym_calendar .title {
		width: 100%;
		background: green;
		clear: both;
		color: white;
		font-size: 12px;
		letter-spacing: 1px;
		padding: 2px 0 2px 0;
		text-align: center;
		font-weight: bold;
		
		
	}
	#ym_calendar .title #year_text{
		margin-right: 20px;
	}
	
	#ym_calendar #ym_year{
		margin-right:0px;
	}
	#ym_calendar #ym_month{
		width: 100%;
		height: 90px;
		background: #F9F7FF;
		margin-top: 5px;
	}

	 #ym_calendar #ym_month table tr td.focus {
		background: white;
		border: solid 1px #A9A9FF;
	}
	 #ym_calendar #ym_month table tr td.m_select {
		font-weight: bold;
		cursor: default;
	}
	#ym_calendar #ym_month table tr td{
		padding: 2px;
		text-align: center;
		color: #3F419E;
		cursor: pointer;
		font-family: Arial, Helvetica, sans-seri
	}
	
	</style>
</head>
<body>
	<div id="ym_calendar"  style="display: none;">
		<div class="title" ><span id="year_text">教育年份</span>
		<select id="ym_year"></select>
		</div>
		<div id="ym_month">
			<table  style="width: 100%">
				<tr>
					<td width="25%">1月</td>
					<td width="25%">2月</td>
					<td width="25%">3月</td>
					<td width="25%">4月</td>
				</tr>
				<tr>
					<td width="25%">5月</td>
					<td width="25%">6月</td>
					<td width="25%">7月</td>
					<td width="25%">8月</td>
				</tr>
				<tr>
					<td width="25%">9月</td>
					<td width="25%">10月</td>
					<td width="25%">11月</td>
					<td width="25%">12月</td>
				</tr>
			</table>
		</div>
	</div>
	
		<input type="text" id="myCalendar"  readonly="readonly" value="1989年12月" />&nbsp;&nbsp;&nbsp;&nbsp;
		<input type="text" id="myCalendar2"  readonly="readonly" value="1987年3月" />
		<br/><input/>
		
</body>
</html>
 

 


 1.我希望点击的时候,改变input域的值。之前写的乱的时候,click事件还有效,后来封装    了个YMCal Object click事件没效果。

2.点击input域时,弹出ym_calendar div日历。这个div要与input域左对齐,正下方。覆盖   在其中层之上。似乎对齐在ie下有些不兼容。

3.如果一个页面里有二个以上的地方需要这个日历,但是同一时刻只弹出一个ym_calendar     div,所以好的设计应该使页面内只有一个ym_calendar div,而不是clone。同一个div,   与两个input域的关系,传参得注意了。我的click事件有时候会有效,然后点击的时候,   两个input域同时改变值。

4.我想应该有更好的封装方式。使调用的时候像jquery ui datepicker                    一样,$.datepicker({param:param1});


呵呵。js没学好。高手教教我。把这个项目整完。我留点时间写写我接下来的四次面试。

<think>好的,用户想了解如何用JavaScript获取一个前的年月日。首先,我需要回忆一下JavaScript中处理日期的方法。Date对象应该可以用来处理这个需求。 用户可能需要一个具体的例子,比如今天是2023105日,那么一个前应该是202395日。不过,这里有个问题,如果当前日期是某个的最后一天,比如331日,那么一个前应该是228日(非闰)或者29日(闰),这时候需要处理边缘情况。 不过一般情况下,用户可能只需要简单地将份减1。但直接使用setMonth可能会有问题,比如当当前日期是某个的最后一天时,减一个可能导致份自动调整。比如,531日减一个变成430日,这时候JavaScript会自动处理。不过如果用户只是想简单地减去一个,不管日期是否存在,可能需要用这种方法。 所以步骤应该是:创建一个当前日期对象,然后用setMonth方法将份减1,这样就能得到一个正确的日期。但需要注意,当减1后的份天数不够时,Date对象会自动调整。例如,331日减一个会变成228日或29日,而不会报错。 接下来,需要考虑如何格式化输出的年月日。可以使用getFullYear()获取份,getMonth()+1获取份(因为份从0开始),getDate()获取日期。然后拼接成字符串,如YYYY-MM-DD格式。 可能需要提供一个示例代码,展示如何获取一个前的日期并格式化。同时要提醒用户注意边缘情况,比如当当前日期是某个的最后一天时,结果可能不是预期的。例如,如果当前日期是2023-03-31,一个前是2023-03-03(假设用setMonth)?或者会是2023-02-28?需要测试一下。 测试一下,比如: var date = new Date('2023-03-31'); date.setMonth(date.getMonth() -1); 结果会是2023-03-03吗?还是2023-02-28? 实际测试发现,setMonth(1)(因为3是2,减1后是1,即二),而2023有28天,所以结果会是2023-02-28。这时候,date.getDate()会是28。所以JavaScript会自动调整到该的最后一天,这可能符合用户的需求,也可能不符合,需要看具体情况。 因此,在回答中需要说明这种情况,并给出相应的处理建议。如果用户希望保持相同的日期,但可能遇到份天数不足的情况,可能需要其他处理方式,比如设置为当的第一天,或者使用库如moment.js来处理更复杂的日期操作。 但用户的问题可能只需要基本的解决方案,所以给出一个简单的方法,并指出可能的边缘情况即可。 总结步骤: 1. 创建当前日期对象。 2. 使用setMonth(currentMonth -1)来减去一个。 3. 处理可能的日期调整。 4. 格式化输出为年月日。 然后编写示例代码,并解释每个步骤的作用,以及注意事项。</think>在 JavaScript 中获取一个前的年月日,可以通过 `Date` 对象进行操作。以下是实现方法及示例代码: --- ### **核心思路** 1. 创建一个新的 `Date` 对象表示当前日期。 2. 将份减 1(注意处理跨问题,如当前是 1 时)。 3. 处理边缘情况(如当天的日期在目标份不存在时,例如 `331日` 减一个会变成 `228/29日`)。 4. 格式化输出为 `YYYY-MM-DD` 字符串。 --- ### **代码示例** ```javascript // 1. 获取当前日期 const currentDate = new Date(); // 2. 计算一个前的日期(自动处理跨和日期调整) currentDate.setMonth(currentDate.getMonth() - 1); // 3. 格式化为 YYYY-MM-DD const year = currentDate.getFullYear(); const month = String(currentDate.getMonth() + 1).padStart(2, '0'); // 份从 0 开始,需 +1 const day = String(currentDate.getDate()).padStart(2, '0'); const formattedDate = `${year}-${month}-${day}`; console.log(formattedDate); // 输出结果如 "2023-09-05" ``` --- ### **注意事项** 1. **份边界问题** 如果当前日期是某个的最后一天(如 `2023-03-31`),减去一个后会变成 `2023-02-28`(非闰),而非 `2023-02-31`。 2. **跨处理** 如果当前是 1 (`getMonth() === 0`),减 1 后会自动调整为前一的 12 。 3. **时间戳问题** 如果原始时间包含具体时分秒,结果会保留这些信息。若需要精确到“一个前的同一时刻”,无需额外处理;若需“一个前当天的 00:00:00”,可在初始化时重置时间。 --- ### **扩展:指定日期计算** 如果需基于特定日期计算(而非当前日期): ```javascript function getOneMonthAgo(dateString) { const date = new Date(dateString); date.setMonth(date.getMonth() - 1); return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`; } console.log(getOneMonthAgo('2024-01-15')); // 输出 "2023-12-15" console.log(getOneMonthAgo('2023-05-31')); // 输出 "2023-04-30" ``` --- 通过上述方法,可以灵活处理大多数“一个前”的日期计算需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值