前端攻城狮---js对象的高级使用之日历案例

Date api

在学日历案例之前,我们先来了解一下日历类的相关api Date

首先我们要先new 一个Data对象

	     var date = new Date(); // 当前系统时间
	      // 获取年月日 周几
         console.log(date.getFullYear()); // 2018
	      console.log(date.getMonth()); // 6 代表7月 因为从0计数
	      console.log(date.getDate()); // 17   日
         
         //  周几
         console.log(date.getDay()); // 0-6  0代表周日 1代表周一 ....

         console.log(date.getHours());
         console.log(date.getMinutes());
         console.log(date.getSeconds());
         console.log(date.getMilliseconds());

         console.log(date.getTime()); // 返回的是自1970/1/1 0:0:0 到当前系统时间之间的毫秒数

         // 2016  5 7 
         var date2 = new Date(2016,4,7);
         console.log(date2.getMonth());// 3
         var date3 = new Date(1000); 
         console.log(date3.getMinutes());// 0
         console.log(date3.getSeconds()); // 1

         // Date.parse("2017-08-09")

         console.log(new Date() - 1);// 时间戳

日历 

先来看看效果图

文章的编辑模式变了,我眼前一亮,动图上次不成功,着实有些纳闷。

首先会有一个输入框,一开始就显示当前的事件,在输入框未获取焦点或者点击外面空白处的时候,下面的日历组件不显示,反之都显示。会有两个下拉框,提供年月来选择,点击日期,会有选中的样式,并且输入框的时间也跟着改变。若点击到上个月或者是下个月的日期,则会调转到想要月份的日期,并显示选中的日期。

现附上最基本的代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style type="text/css">
      *{
        margin: 0;
        padding: 0;
      }
      #calendar{
        width: 300px;
        margin: 50px auto;
        position: relative;
        padding: 5px;
        border: 1px solid black;
        box-sizing: border-box;
      }
      table{
        width: 100%;
      }
      table,tr,th,td{
        background-color: #333;
        font-size: 16px;
        color: green;
        height: 40px;
        border: 1px solid white;
        text-align: center;
        border-collapse: collapse;
      }
      .isclick{
        color:white;
        background-color: skyblue;
      }
      .notNow{
        /*opacity: 0.2;*/
        /*filter: alpha(opacity=20);*/
        background-color: #ccc;
      }
      td{
        color: white;
      }
  </style>
</head>
<body>
    <div id="calendar"></div>
    <script type="text/javascript" src="calendardemo.js"></script>
    <script type="text/javascript">
        new Calendar({"id":"calendar"});
    </script>
</body>
</html>

我们将日历封装到js里面,我们已经初步完成了除了事件的其他全部逻辑

(function(){
	window.Calendar = Calendar;
	function Calendar(Json){
		this.dom = "";
		this.inputText="";
		this.selectYear = "";
		this.selectMonth = "";
		this.calendarTable = "";
		this.tdList = "";
		this.calendarBody = "";
		this.init(Json);
		this.year = (new Date()).getFullYear();//年
		this.month = (new Date()).getMonth();//月
		this.day = (new Date()).getDate();//日
		this.setDate(this.year,this.month,this.day);
		this.bind();
	}
	Calendar.prototype.init = function(Json){
		//总的父容器
		this.dom = document.getElementById(Json["id"]);
		//输入框
		this.inputText = document.createElement("input");
		this.inputText.type = "text";
		this.dom.appendChild(this.inputText);
		//日历的父容器
		this.calendarBody = document.createElement("div");
		//年选择器
		this.selectYear = document.createElement("select");
		for(var i = 1980;i<=2040;i++){
			var yearOption = document.createElement("option");
			yearOption.innerHTML = i+"";
			yearOption.value = i+""
			this.selectYear.appendChild(yearOption);
		}
		this.calendarBody.appendChild(this.selectYear);
		//月选择器
		this.selectMonth = document.createElement("select");
		for(var i = 1;i<=12;i++){
			var monthOption = document.createElement("option");
			monthOption.innerHTML = i+"月";
			monthOption.value = i+"月"
			this.selectMonth.appendChild(monthOption);
		}
		this.calendarBody.appendChild(this.selectMonth);
		//日历内容的table
		this.calendarTable = document.createElement("table");
		var weekDayList = ["日","一","二","三","四","五","六"];
		var calendartitle = document.createElement("tr");
		for(var i = 0;i<weekDayList.length;i++){
			var th = document.createElement("th");
			th.value = weekDayList[i];
			th.innerHTML = weekDayList[i];
			calendartitle.appendChild(th);
		}
		this.calendarTable.appendChild(calendartitle);
		for(var i = 0;i<6;i++){
			var tr = document.createElement("tr");
			for(var b = 0;b<7;b++){
				var td = document.createElement("td");
				tr.appendChild(td);
			}
			this.calendarTable.appendChild(tr);
		}
		this.calendarBody.appendChild(this.calendarTable);
		this.tds = this.calendarTable.getElementsByTagName("td");
		this.dom.appendChild(this.calendarBody);
	}
	/*
			月份未加1
	*/
	Calendar.prototype.setDate = function(year,month,day){
		this.year = year;
		this.month = month;
		day&&(this.day = day);//因为通过下拉框是不传入day
		this.selectYear.value = year;
		this.selectMonth.value = (month+1)+"月";

		//当前月多少天
		var nowMonthDay=new Date((new Date(year,month+1,1)-1)).getDate();
		console.log("nowMonthDay "+nowMonthDay+" "+new Date((new Date(year,month+1)-1)).getMonth());
		//当前月的上个月多少天
		var lastMonthDay = new Date((new Date(year,month,1)-1)).getDate();
		console.log("lastMonthDay "+lastMonthDay+" "+new Date((new Date(year,month)-1)).getMonth());
		//当前月的下个月多少天
		var nextMonthDay=new Date((new Date(year,month+2,1)-1)).getDate();
		console.log("nextMonthDay "+nextMonthDay+" "+new Date((new Date(year,month+2)-1)).getMonth());
		//当前月的第一天是星期几
		var nowMonthFirstWeekDay=new Date((new Date(year,month,1))).getDay();
		console.log("nowMonthFirstWeekDay "+nowMonthFirstWeekDay);
		//显示当前月份的天数
		for(var i = 1;i<=nowMonthDay;i++){
			if(nowMonthFirstWeekDay==0){//若是星期天 如要上面留空一行,不然无法通过日历跳转到下一个月
				this.tds[6+i].value = i;
				this.tds[6+i].innerHTML = i;
				this.tds[6+i].className = "";
				if(day){//若是选中则显示被选中的样式
					if (i==day) {
						this.tds[6+i].className = "isclick";
					}
				}
			}
			else{
				this.tds[nowMonthFirstWeekDay+i].value = i;
				this.tds[nowMonthFirstWeekDay+i].innerHTML = i;
				this.tds[nowMonthFirstWeekDay+i].className = "";
				if(day){//若是选中则显示被选中的样式
					if (i==day) {
						this.tds[6+i].className = "isclick";
					}
				}
			}
		}
		if(nowMonthFirstWeekDay==0){
			for(var i = 0;i<=6;i++){//显示上个月的day
				this.tds[i].innerHTML = lastMonthDay-6+i;
				this.tds[i].value = lastMonthDay-6+i;
				this.tds[i].className = "";
				this.tds[i].className = "notNow";
			}
			for(var i = 6+nowMonthDay+1;i<42;i++){//显示下个月的day
				this.tds[i].innerHTML = i-6-nowMonthDay;
				this.tds[i].value =  i-6-nowMonthDay;
				this.tds[i].className = "";
				this.tds[i].className = "notNow";
			}
		}else{
			for(var i = 0;i<=nowMonthFirstWeekDay;i++){
				this.tds[i].innerHTML = lastMonthDay-nowMonthFirstWeekDay+i;
				this.tds[i].value = lastMonthDay-nowMonthFirstWeekDay+i;
				this.tds[i].className = "";
				this.tds[i].className = "notNow";
			}
			for(var i = nowMonthFirstWeekDay+nowMonthDay+1;i<42;i++){
				this.tds[i].innerHTML = i-nowMonthFirstWeekDay-nowMonthDay;
				this.tds[i].value =  i-nowMonthFirstWeekDay-nowMonthDay;
				this.tds[i].className = "";
				this.tds[i].className = "notNow";
			}
		}
		this.inputText.value = day?year+"-"+(month+1)+"-"+day:year+"-"+(month+1);

	}
	Calendar.prototype.bind = function(){
		
	}
})()

大部分的内容都有注解。首先我们来了解一下大致的流程。

我们将日历组件编写于js里面。

      首先将所有的业务逻辑放到了IIFE的函数体里,接着就是组件的初始化。

      init()方法里,我们创建了一个输入框,两个下拉框,一个table表格。

      接着讲数据的显示都放到碗里setDate方法里,需要传入三个参数(年 月 日),从而去显示表格中日历的事件。

接下来我们要编写日历的事件----->bind()方法

Calendar.prototype.bind = function(){
		var mthis = this;
		this.selectYear.onchange = function(){
			mthis.inputText.value = "";
			mthis.setDate(parseInt(mthis.selectYear.value),mthis.month,mthis.day);
		}
		this.selectMonth.onchange = function(){
			mthis.inputText.value = "";
			mthis.setDate(mthis.year,parseInt(mthis.selectMonth.value),mthis.day);	
		}
		this.inputText.onfocus = function(){
			mthis.calendarBody.style.display="block";
		}
		for(var i = 0;i<42;i++){
			this.tds[i].index = i;
			this.tds[i].onclick = function(){
				var index = this.index;
				console.log(index+" "+mthis.thisnowMonthDay);
				if(mthis.thisnowMonthFirstWeekDay==0){
					if(index>=0&&index<=6){//上个月
						mthis.toChange(mthis.thislastMonthDay-6+index,1);
					}else if(index<=(6+mthis.thisnowMonthDay)){//当前
						mthis.toChange(index-6,2);
					}else{//下个月
						mthis.toChange(index-6-mthis.thisnowMonthDay,3);
					}
				}else{
					if(index>=0&&index<=mthis.thisnowMonthFirstWeekDay){//上个月
						mthis.toChange(mthis.thislastMonthDay-mthis.thisnowMonthFirstWeekDay+index,1);
					}else if(index<=(mthis.thisnowMonthFirstWeekDay+mthis.thisnowMonthDay)){//当前
						mthis.toChange(index-mthis.thisnowMonthFirstWeekDay,2);
					}else{//下个月
						mthis.toChange(index-mthis.thisnowMonthFirstWeekDay-mthis.thisnowMonthDay,3);
					}
				}
			}
		}

	}
	Calendar.prototype.toChange =function(day,type){
		console.log(day+" "+type);
		if (type==1) {
			if(this.month==0){
				this.month = 11;
				this.year--;
				this.day = day;
			}else{
				this.month--;
				this.day = day;
			}
			console.log(this.year+" "+this.month+" "+this.day);
			this.setDate(this.year,this.month,this.day);
		}else if(type ==2){
			this.day = day;
			console.log(this.year+" "+this.month+" "+this.day);
			this.setDate(this.year,this.month,this.day);
		}else {
			if (this.month==11) {
				this.month = 0;
				this.year++;
				this.day = day;
			}else{
				this.month++;
				this.day = day;
			}
			console.log(this.year+" "+this.month+" "+this.day);
			this.setDate(this.year,this.month,this.day);
		}
	}

js高级相关部分日历组件讲完了,接下来会来讲解ajax的相关知识点,如有表达错的请谅解,并请提出指出,且修改错误,望能共同进步。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值