从0开始,手写一个日历控件

先说说,从0开始搭建日历控件思路:

  1. HTML结构: 首先需要在HTML中创建一个容器元素,用于容纳日期选择器。可以使用
    标签,并为其指定一个唯一的ID。在容器元素内部,可以添加一些元素来显示当前选定的日期和触发日期选择的按钮
    2.CSS样式: 使用CSS样式为日期选择器容器和相关元素进行布局和美化。可以使用position、display和z-index等属性来控制其在页面上的位置和层级。还可以使用各种CSS样式属性来调整其外观,如背景颜色、字体样式和大小等。
  2. JavaScript逻辑: 编写JavaScript逻辑来实现日期选择器的功能。可以使用事件监听器来触发日期选择器的显示和隐藏。在展示日期选择器时,可以动态生成日历布局,并为每个日期单元格添加相应的事件监听器。还可以根据用户的选择来更新日期显示和隐藏日期选择器单的思路示例代码

示例图片:
在这里插入图片描述
css代码:

.calendar-form{
			margin-left: 100px;
			margin-top: 200px;
		}
		.calender-header{
			width: 100%;
			height: 100%;
			display: inline-flex;
			justify-content: space-between;
			align-items:center;
			box-sizing: border-box;
		}
		.calender-left{
			height: 14px;
			text-align: left;
			display: inline-flex;
			box-sizing: border-box;
		}
		.calender-left span{
			margin-right: 10px;
		}
		.calender-right{
			height: 14px;
			text-align: right;
			display: inline-flex;
			box-sizing: border-box;
		}
		.calender-right span{
			margin-left: 10px;
		}
		.calender-center{
			text-align: center;
		}
		.calendar-div{
			width: 300px;
			box-sizing: border-box;
			padding: 8px;
			box-shadow: 0 1px 3px hsl(0deg 0% 7% / 10%);
		}
		
		.calendar-div::before{
			content: '';
			display: block;
			position: absolute;
			width: 10px;
			height: 10px;
			top: -6px;
			left: 10px;
			transform: rotate(-45deg);
			background-color: white;
			border: 1px;
			border-style: solid;
			border-color: #e4e7ed #e4e7ed transparent transparent;
		}
		.calendar{
			background-color: #fff;
			border-collapse: collapse;
			border: 1px solid transparent;
			width: 100%;
			height: 200px;
		}
		.prev-month{
			color: rgba(194, 194, 194, 1);
		}
		.next-month{
			color: rgba(194, 194, 194, 1);
		}
		.current-month{
			color: rgb(51, 54, 57);
		}
		.week-tr{
			height: 40px;
			border-bottom: 1px solid black;
			color: rgb(51, 54, 57);
		}
		.week-td{
			width: 25px;
			height: 24px;
			padding: 2px 0px 0px 3px;
			text-align: center;
			color: rgb(51, 54, 57);
		}
		.day {
			width: 24px;
			height: 24px;
			padding: 10px;
			border: 1px solid rgb(239, 239, 245);
			text-align: center;
		}
		.day:hover{
			background-color: rgb(243, 243, 245);
		}
		.current{
			background-color: #2d8cf0;
		}
		.calender-button{
			width: 100%;
			height: 100%;
			display: inline-flex;
			justify-content: right;
			align-items: center;
		}
		.calender-button button{
			margin: 3px 3px;
			background-color: #fff;
			border: 1px solid rgb(239, 239, 245);
			border-radius: 3px;
		}
		.calender-button button:hover{
			border: 1px solid #2d8cf0;
		}
		.calendar-input{
			width: 300px;
			height: 23px;
			border: 1px solid #2d8cf0;
			outline: none;
			padding: 2px;
			border-radius: 4px;
			color: #75849a;
		}

html部分

	<div class="calendar-form">
			<label>选择日历</label>
			<input class="calendar-input" />
	</div>

js部分

		//创建节点到页面
			createDom();
			let calendar=document.getElementsByClassName('calendar-input')[0];
			let calendarDiv=document.getElementsByClassName('calendar-div')[0];
			//将两个节点关联在一起
			association(calendar,calendarDiv)
			
			// 获取当前日期
			var currentDate = new Date();
			
			function now(){
				currentDate = new Date();
				renderCalendar(currentDate,'calendar')
				calendar.value=currentDate.toISOString().split("T")[0]
			}
			
			function clearDate(){
				calendar.value='';
			}
			
			//上一年
			function previousYear(){
				currentDate.setFullYear(currentDate.getFullYear() - 1); // 将年份减去1
				renderCalendar(currentDate,'calendar')
			}
			
			function nextYear(){
				currentDate.setFullYear(currentDate.getFullYear() + 1); // 将年份减去1
				renderCalendar(currentDate,'calendar')
			}
			
			function previousMonth(){
				var currentMonth = currentDate.getMonth(); // 获取当前月份
				
				if (currentMonth === 0) { // 如果当前月份是一月
				  currentDate.setFullYear(currentDate.getFullYear() - 1); // 将年份减去1
				  currentDate.setMonth(11); // 设置月份为十二月
				} else {
				   currentDate.setMonth(currentMonth - 1); // 将月份减去1
				}
				renderCalendar(currentDate,'calendar');
			}
			
			function nextMonth(){
				var currentMonth = currentDate.getMonth(); // 获取当前月份
				
				if (currentMonth === 11) { // 如果当前月份是一月
				  currentDate.setFullYear(currentDate.getFullYear() + 1); // 将年份减去1
				  currentDate.setMonth(0); // 设置月份为十二月
				} else {
				   currentDate.setMonth(currentMonth + 1); // 将月份减去1
				}
				renderCalendar(currentDate,'calendar');
			}
			
			
			
			renderCalendar(currentDate,'calendar')
			
			function renderCalendar(currentDate,id){
				let day=currentDate.getDate();
				
				// 获取当前年份
				var currentYear = currentDate.getFullYear();
				
				// 获取当前月份
				var currentMonth = currentDate.getMonth();
				
				// 创建一个包含每个月份的名称的数组
				var months = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'];
				
				// 创建一个包含每个星期的名称的数组
				var weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
				
				// 获取当前月份的第一天
				var firstDay = new Date(currentYear, currentMonth, 1);
				
				// 获取当前月份的最后一天
				var lastDay = new Date(currentYear, currentMonth + 1, 0);
				
				// 创建日历表格
				var calendar = "<table class='calendar'>";
				
				// 添加表头行
				calendar += "<tr><td colspan='7'><div class='calender-header'>";
				calendar+='<span class="calender-left">';
				calendar+='		<span οnclick="previousYear()"><svg  width="14" height="14" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g fill="currentColor" fill-rule="nonzero"><path d="M8.73171,16.7949 C9.03264,17.0795 9.50733,17.0663 9.79196,16.7654 C10.0766,16.4644 10.0634,15.9897 9.76243,15.7051 L4.52339,10.75 L17.2471,10.75 C17.6613,10.75 17.9971,10.4142 17.9971,10 C17.9971,9.58579 17.6613,9.25 17.2471,9.25 L4.52112,9.25 L9.76243,4.29275 C10.0634,4.00812 10.0766,3.53343 9.79196,3.2325 C9.50733,2.93156 9.03264,2.91834 8.73171,3.20297 L2.31449,9.27241 C2.14819,9.4297 2.04819,9.62981 2.01448,9.8386 C2.00308,9.89058 1.99707,9.94459 1.99707,10 C1.99707,10.0576 2.00356,10.1137 2.01585,10.1675 C2.05084,10.3733 2.15039,10.5702 2.31449,10.7254 L8.73171,16.7949 Z"></path></g></g></svg></span>';
				calendar+='		<span οnclick="previousMonth()"><svg  width="14" height="14" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12.2674 15.793C11.9675 16.0787 11.4927 16.0672 11.2071 15.7673L6.20572 10.5168C5.9298 10.2271 5.9298 9.7719 6.20572 9.48223L11.2071 4.23177C11.4927 3.93184 11.9675 3.92031 12.2674 4.206C12.5673 4.49169 12.5789 4.96642 12.2932 5.26634L7.78458 9.99952L12.2932 14.7327C12.5789 15.0326 12.5673 15.5074 12.2674 15.793Z" fill="currentColor"></path></svg></span>'
				calendar+='</span>';
				calendar+="<span class='calender-center'>"+ months[currentMonth] + " " + currentYear + "</span>"
				calendar+='<span class="calender-right">';
				calendar+='		<span οnclick="nextMonth()"><svg  width="14" height="14" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M7.73271 4.20694C8.03263 3.92125 8.50737 3.93279 8.79306 4.23271L13.7944 9.48318C14.0703 9.77285 14.0703 10.2281 13.7944 10.5178L8.79306 15.7682C8.50737 16.0681 8.03263 16.0797 7.73271 15.794C7.43279 15.5083 7.42125 15.0336 7.70694 14.7336L12.2155 10.0005L7.70694 5.26729C7.42125 4.96737 7.43279 4.49264 7.73271 4.20694Z" fill="currentColor"></path></svg></span>'
				calendar+='		<span οnclick="nextYear()"><svg  width="14" height="14" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg"><g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g fill="currentColor" fill-rule="nonzero"><path d="M11.2654,3.20511 C10.9644,2.92049 10.4897,2.93371 10.2051,3.23464 C9.92049,3.53558 9.93371,4.01027 10.2346,4.29489 L15.4737,9.25 L2.75,9.25 C2.33579,9.25 2,9.58579 2,10.0000012 C2,10.4142 2.33579,10.75 2.75,10.75 L15.476,10.75 L10.2346,15.7073 C9.93371,15.9919 9.92049,16.4666 10.2051,16.7675 C10.4897,17.0684 10.9644,17.0817 11.2654,16.797 L17.6826,10.7276 C17.8489,10.5703 17.9489,10.3702 17.9826,10.1614 C17.994,10.1094 18,10.0554 18,10.0000012 C18,9.94241 17.9935,9.88633 17.9812,9.83246 C17.9462,9.62667 17.8467,9.42976 17.6826,9.27455 L11.2654,3.20511 Z"></path></g></g></svg></span>';
				calendar+='</span>';
				calendar+="</div></td></tr>";
				// 添加星期行
				calendar += "<tr class='week-tr'>";
				for (var i = 0; i < weekdays.length; i++) {
				  calendar += "<td class='week-td'>" + weekdays[i] + "</td>";
				}
				calendar += "</tr>";
				
				var prevMonthLast= new Date(currentYear, currentMonth, 0);
				// 获取上个月的最后一天
				var prevMonthLastDay = prevMonthLast.getDate();
				
				// 获取每个月第一天是星期几
				var firstDayOfWeek = firstDay.getDay();
				if (firstDayOfWeek === 0) {
				   firstDayOfWeek = 7;  // 如果是星期日,则将其转换为7
				}
				
				// 添加日期行
				var dayCounter = 1; // 计数器,用于累加日期
				
				// 添加日期行
				for (var row = 1; row <= 6; row++) {
				  calendar += "<tr>";
				
				  for (var col = 0; col < 7; col++) {
				    if (row === 1 && col < firstDayOfWeek) {
				         // 添加上个月的日期
				         var prevMonthDate = prevMonthLastDay - firstDayOfWeek + col + 1;
				         let year=getYear(currentDate,false)
				         let month=getMonth(currentDate,false)+1;
						 calendar += "<td οnclick='getDay(this)'  year="+year+" month="+month+" day="+prevMonthDate+"  class='prev-month day'>" + prevMonthDate + "</td>";
				       } else if (dayCounter > lastDay.getDate()) {
				         // 添加下个月的日期
				         var nextMonthDate = dayCounter - lastDay.getDate();
						 let year=getYear(currentDate,true)
						 let month=getMonth(currentDate,true)+1;
				         calendar += "<td οnclick='getDay(this)'  year="+year+" month="+month+" day="+nextMonthDate+" class='next-month day'>" + nextMonthDate + "</td>";
				         dayCounter++;
				       } else {
						 if(dayCounter==day){
							 // 添加当前月的日期
							 let month=currentMonth+1;
							 calendar += "<td οnclick='getDay(this)'  year="+currentYear+" month="+month+" day="+dayCounter+" class='current-month current day'>" + dayCounter + "</td>";
						 }else{
							 // 添加当前月的日期
							 let month=currentMonth+1;
							 calendar += "<td οnclick='getDay(this)'  year="+currentYear+" month="+month+" day="+dayCounter+" class='current-month  day'>" + dayCounter + "</td>";
						 }
				         dayCounter++;
				       }
				  }
				
				  calendar += "</tr>";
				}
				calendar += "<tr class='last-tr'><td colspan='7'>";
				calendar +="	<div class='calender-button'>";
				calendar +="		<button οnclick='clearDate()'>清除</button>"
				calendar +="		<button οnclick='now()'>此刻</button>"
				calendar +="	</div>";
				calendar += "</td></tr>";
				
				// 关闭表格
				calendar += "</table>";
				
				
				document.getElementById(id).innerHTML=calendar;
			}
			
			function getYear(curentDate,isNext){
				var currMonth = curentDate.getMonth(); // 获取当前月份
				if(isNext){
					if (currMonth === 11) { // 如果当前月份是一月
						return curentDate.getFullYear() + 1;
					} else {
						return curentDate.getFullYear();
					}
				}else{
					if (currMonth === 0) { // 如果当前月份是一月
						return curentDate.getFullYear() - 1;
					} else {
						return curentDate.getFullYear();
					}
				}
			}
			
			function getMonth(curentDate,isNext){
				var currMonth = curentDate.getMonth(); // 获取当前月份
				if(isNext){
					if (currMonth === 11) { // 如果当前月份是一月
						return 1;
					} else {
						return currMonth + 1;
					}
				}else{
					if (currMonth === 0) { // 如果当前月份是一月
						return 11;
					} else {
						return currMonth - 1;
					}
				}
			}
			
			function association(target,source){
				source.style.position='absolute';
				source.style.display='none';
				target.addEventListener('click',()=>{
					source.style.display = 'block';
					// source.style.width = target.offsetWidth +"px";
					source.style.left = target.offsetLeft + "px";
					source.style.top = target.offsetTop + target.offsetHeight+ 10 + "px";
				})
				
				
				
				document.addEventListener('click', function(event) {
					  var sourceDivRect = source.getBoundingClientRect(); // 获取该div元素相对于视口的位置信息
					  var targetDivRect = target.getBoundingClientRect();
					  var mouseX = event.clientX; // 获取鼠标当前位置的x坐标
					  var mouseY = event.clientY; // 获取鼠标当前位置的y坐标
					  if (mouseX >= sourceDivRect.left && mouseX <= sourceDivRect.right && mouseY >= sourceDivRect.top && mouseY <= sourceDivRect.bottom) {
							console.log('鼠标在div区域内');
					  } else if( mouseX >= targetDivRect.left && mouseX <= targetDivRect.right && mouseY >= targetDivRect.top && mouseY <= targetDivRect.bottom){
						    console.log('鼠标在div区域内');
					  } else {
							console.log('鼠标在div不在区域内');
						    source.style.display = 'none';
					  }
				});
			}
			
		
			function createDom(){
				var newNode = document.createElement("div");
				newNode.classList.add('calendar-div');
				
				var newNode2 = document.createElement("div");
				newNode2.id="calendar";
				
				newNode.appendChild(newNode2);
				// 将节点添加到body上
				document.body.appendChild(newNode);
			}
			
			function getDay(e){
				let year=e.getAttribute('year');
				let month=e.getAttribute('month');
				let day=e.getAttribute('day');
				month=month;
				if(month.length==1){
					month='0'+month;
				}
				if(day.length==1){
					day='0'+day;
				}
				let  dateday=year+'-'+month+'-'+day;
				calendar.value=dateday;
			}
  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 手写一个日历可能比较复杂,但可以使用 JavaScript 的 `Date` 对象和一些日期处理函数来实现。下面是一个简单的实现: ``` // 获取当前日期 var now = new Date(); // 获取当前月份 var month = now.getMonth(); // 获取当前年份 var year = now.getFullYear(); // 创建日历的表格 var table = document.createElement("table"); table.setAttribute("border", "1"); table.setAttribute("cellspacing", "0"); table.setAttribute("cellpadding", "5"); document.body.appendChild(table); // 创建表格的标题行 var caption = table.createCaption(); caption.innerHTML = year + "年" + (month + 1) + "月"; var thead = document.createElement("thead"); table.appendChild(thead); var tr = document.createElement("tr"); thead.appendChild(tr); var th = null; for (var i = 0; i < 7; i++) { th = document.createElement("th"); tr.appendChild(th); } th.innerHTML = "星期日"; th.innerHTML = "星期一"; th.innerHTML = "星期二"; th.innerHTML = "星期三"; th.innerHTML = "星期四"; th.innerHTML = "星期五"; th.innerHTML = "星期六"; // 创建表格的主体部分 var tbody = document.createElement("tbody"); table.appendChild(tbody); for (var i = 0; i < 6; i++) { tr = document.createElement("tr"); tbody.appendChild(tr); for (var j = 0; j < 7; j++) { td = document.createElement("td"); tr.appendChild(td); } } // 计算当前月份的天数 var days = new Date(year, month + 1, 0).getDate(); // 计算当前月份第一天是星期几 var firstDay = new Date(year, month, 1).getDay(); // 填充表格的主体部分 var count = 1; for (var i = 0; i < 6; i++) { for (var j = 0; j < 7; j++) { if (i === 0 && j < firstDay) { // 填充空 ### 回答2: 要手写一个JS星期日历,可以按照以下步骤进行: 1. 首先创建一个HTML文件,定义一个容器元素,用于显示日历的表格。 2. 在JS文件中,使用`Date`对象获取当前日期的年份和月份信息,并存储在变量中。 3. 使用`switch`语句确定当前月份的天数,并存储在一个名为`daysInMonth`的变量中。 4. 创建一个名为`calendar`的函数,用于创建和填充日历表格。 5. 在`calendar`函数中,使用`document.createElement()`方法创建HTML元素:表格、行和单元格。 6. 在循环中,根据`daysInMonth`变量的值创建和填充表格的行和单元格。 7. 在每个单元格中,使用Date对象的`getDate()`方法获取日期,并将其填充到单元格中。 8. 使用CSS样式来美化日历表格,例如设置表格边框、单元格宽度、字体样式等。 9. 调用`calendar`函数,将日历表格添加到HTML容器元素中,以便在网页上显示出来。 以下是一个简单的示例代码: ```html <!DOCTYPE html> <html> <head> <title>JS手写星期日历</title> <style> table { border-collapse: collapse; } td { border: 1px solid black; width: 50px; height: 50px; text-align: center; font-weight: bold; } </style> </head> <body> <div id="calendar"></div> <script> var currentDate = new Date(); var currentYear = currentDate.getFullYear(); var currentMonth = currentDate.getMonth(); var daysInMonth; switch(currentMonth) { case 1: if((currentYear % 4 == 0 && currentYear % 100 != 0) || currentYear % 400 == 0) { daysInMonth = 29; } else { daysInMonth = 28; } break; case 3: case 5: case 8: case 10: daysInMonth = 30; break; default: daysInMonth = 31; } function calendar() { var container = document.getElementById("calendar"); var table = document.createElement("table"); for(var i = 0; i < daysInMonth/7; i++) { var row = document.createElement("tr"); for(var j = 0; j < 7; j++) { var cell = document.createElement("td"); var day = i * 7 + j + 1; if(day <= daysInMonth) { cell.innerHTML = day; } row.appendChild(cell); } table.appendChild(row); } container.appendChild(table); } calendar(); </script> </body> </html> ``` 这样,一个简单的JS手写星期日历就完成了。运行该代码,即可在网页上显示出一个以当前月份为基础的日历表格。 ### 回答3: 要手写一个星期日历,可以使用JS编写以下代码: ```javascript // 获取当前日期 var today = new Date(); var year = today.getFullYear(); var month = today.getMonth() + 1; var day = today.getDate(); // 获取本月的第一天和最后一天的日期 var firstDay = new Date(year, month - 1, 1); // 注意月份要减1 var lastDay = new Date(year, month, 0); // 获取上个月的最后一天即本月的最后一天 // 获取本月的天数和第一天是星期几 var numDays = lastDay.getDate(); var firstWeekday = firstDay.getDay(); // 定义一个用于存储星期的数组 var weekDays = ["日", "一", "二", "三", "四", "五", "六"]; // 打印日历头部 console.log(year + "年" + month + "月"); console.log("日 一 二 三 四 五 六"); // 打印空白占位符 for (var i = 0; i < firstWeekday; i++) { process.stdout.write(" "); } // 打印日期 for (var j = 1; j <= numDays; j++) { process.stdout.write((j < 10 ? " " : "") + j + " "); if ((firstWeekday + j) % 7 === 0) { // 每行结束换行 console.log(); } } ``` 这段代码首先获取当前日期,然后计算本月的第一天和最后一天的日期,以及本月的天数和第一天是星期几。然后使用一个存储星期的数组,打印日历头部和星期的标题。 接着打印空白占位符,保证第一天之前的日期没有显示。然后利用循环打印日期,如果每行的日期数达到7个就换行。最后得到一个简单的星期日历输出。 注意:以上代码只是一个简单的示例,可能在细节上还有待完善,比如排版、颜色等。如果需求更复杂,可以根据实际需求进行相应的修改和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值