效果圖以下:css
html代碼html
<div class="date-control" id="date-control"> <span id="pre-month">-</span> <p><span id="table-year">2017</span>/<span id="table-month">12</span></p> <span id="next-mont">+</span> </div> <table id="date-table"> <thead> <tr> <th>1</th><th>2</th><th>3</th><th>4</th><th>5</th><th>6</th><th>日</th> </tr> </thead> <tbody> </tbody> </table> <script> var c = new Calendar(); //c.calendarInit(false,2017,11);//第一個參數表明是不是今天的日曆,若是第一個參數爲false,還須要傳遞倆個參數,年和月。 c.calendarInit(true); </script>
css代碼spring
table{ width: 300px; border-collapse:collapse; } th{ border-bottom: 2px solid springgreen; } td{ text-align: center; color: #999; } .this-month{ color: #333; } .today{ color: crimson; } .date-control{ width: 300px; height: 20px; background: silver; position: relative; } .date-control p{ text-align: center; line-height: 20px; color: #fff; } #pre-month,#next-mont{ display: block; height: 20px; width: 20px; color: #fff; position: absolute; top: 0; text-align: center; background: #01cd78; cursor: pointer; user-select: none; } #pre-month{ left: 0; } #next-mont{ right: 0; }
js代碼數組
function Calendar() { this.today = new Date(); this.table = document.getElementById("date-table").getElementsByTagName("tbody")[0]; this.preMontBtn = document.getElementById("pre-month"); this.nextMontBtn = document.getElementById("next-mont"); this.yearText = document.getElementById("table-year"); this.monthText = document.getElementById("table-month"); } Calendar.prototype={ constructor:Calendar, calendarInit:function (_isToday,_y,_m) { if(_isToday){ this.drawTable(this.today.getFullYear(),this.today.getMonth()); this.titleInit(this.today.getFullYear(),this.today.getMonth()+1); }else { this.drawTable(_y,_m-1); this.titleInit(_y,_m) } this.btnListener(); }, getMontInfo:function (_year,_month) { var firstDate = new Date(_year,_month,1); var lastDate = new Date(_year,_month+1,0); return { firstDay:firstDate.getDay()===0?7:firstDate.getDay(), lastDay:lastDate.getDay()===0?7:lastDate.getDay(), days:lastDate.getDate() } }, drawTable:function (_year,_month) { this.table.innerHTML = ""; var allDayNum = this.getDateNum(_year,_month); var rows = allDayNum.length/7; var index = 0; for(var i=0;i<rows;i++){ var tr = document.createElement("tr"); for(var j=0;j<7;j++){ var td = document.createElement("td"); console.log(allDayNum[index].date,index); td.innerText = allDayNum[index].date; if(allDayNum[index].info==="this month"){ td.className="this-month" }else if(allDayNum[index].info==="today"){ td.className="today"; } tr.appendChild(td); index++; } this.table.appendChild(tr); } }, getDateNum:function (_year,_month) { var allDayNum = []; var today = new Date(); var todayInfo = { year:today.getFullYear(), month:today.getMonth(), date:today.getDate() }; var thisMonthInfo = this.getMontInfo(_year,_month); var preMontInfo = this.getMontInfo(_year,_month-1); var info; for(var i=0;i<thisMonthInfo.days;i++){ info = { date:i+1, info:"this month" }; if(_year===todayInfo.year&&_month===todayInfo.month&&i+1===todayInfo.date){ info.info = "today"; } allDayNum[i]=info; } for(i=0;i<thisMonthInfo.firstDay-1;i++){ info = { date:preMontInfo.days-i, info:"pre month" }; allDayNum.unshift(info) } for(i=0;i<7-thisMonthInfo.lastDay;i++){ info = { date:i+1, info:"next month" }; allDayNum.push(info); } return allDayNum; }, btnListener:function () { var that = this; that.preMontBtn.addEventListener("click",function () { var dateInfo = { year:that.yearText.innerText*1, month:that.monthText.innerText*1 }; var newDateInfo = { year:dateInfo.month-1===0?dateInfo.year-1:dateInfo.year, month:dateInfo.month-1===0?12:dateInfo.month-1 }; that.yearText.innerText = newDateInfo.year; that.monthText.innerText = newDateInfo.month; that.drawTable(newDateInfo.year,newDateInfo.month-1); }); that.nextMontBtn.addEventListener("click",function () { var dateInfo = { year:that.yearText.innerText*1, month:that.monthText.innerText*1 }; var newDateInfo = { year:dateInfo.month+1===13?dateInfo.year+1:dateInfo.year, month:dateInfo.month+1===13?1:dateInfo.month+1 }; that.yearText.innerText = newDateInfo.year; that.monthText.innerText = newDateInfo.month; that.drawTable(newDateInfo.year,newDateInfo.month-1); }); }, titleInit:function (y,m) { this.yearText.innerText = y; this.monthText.innerText = m; } };
知識點:app
一、得到今天的日期對象:var today = new Date();this
二、得到某一月第一天和最後一天的日期對象:
var firstDate = new Date(_year,_month,1);//指定(年)月,第一天的日期對象
var lastDate = new Date(_year,_month+1,0);//指定(年)月,最後一天的日期對象spa
三、查看日期對象的相關信息:
假設d是一個日期對象(如:var d = new Date(),或,var d=new Date(2017,12,17))
d.getFullYear();//得到d對應的年
d.getMonth();//得到d對應的月
d.getDate();//得到d對應的星期prototype
四、查看日期對象的信息:
d.toLocaleString()//打印結果爲:2017/12/16 上午9:55:26code
思路概要:(逆向)
結果爲:繪製日曆
繪製table頭部,星期123457
繪製日期數字
獲得日期數字數組
知道這個月有幾天,第一天星期幾,最後一天星期幾(從而,獲得日期數組)。htm
方法解析:
一、如何知道某個月有多少天,第一天星期幾,最後一天星期幾?
方法以下:
function getThisMontInfo(_year,_month) { var firstDate = new Date(_year,_month,1);//當前月第一天 var lastDate = new Date(_year,_month+1,0);//當前月最後一天 return {//返回一個對象 firstDay:firstDate.getDay()===0?7:firstDate.getDay();//當前月第一天的星期(星期日爲0,若是其爲零,讓其變爲7)、 lastDay:lastDate.getDay()===0?7:lastDate.getDay(),//當前月最後一天的星期 days:lastDate.getDate()//當前月有多少天,即最後一天的日期。 } }
二、如何得到日期數組?
方法以下:
//前提知道年和月,即y和m //利用了上面的方法 thisMonthInfo = getThisMontInfo(y,m);//當前月相關信息 preMontInfo = getThisMontInfo(y,m-1);//上個月的相關信息 var allDayNum = []; //向數組中添加當前月日期。 for(i=0;i<thisMonthInfo.days;i++){//thisMonthInfo.days爲指定月的天數 allDayNum[i]=i+1; } //補上上個月的最後幾天 for(i=0;i<thisMonthInfo.firstDay-1;i++){//thisMonthInfo.firstDay這個月第一天的星期 allDayNum.unshift(preMontInfo.days-i)//preMontInfo.days是上個月的天數 } //補上下個月的前幾天 for(i=0;i<7-thisMonthInfo.lastDay;i++){//thisMonthInfo.lastDay這個月最後一天的星期 allDayNum.push(i); }
如何繪製table?
步驟爲:
一、計算須要繪製多少行tr
二、繪製對應行數的tr
三、在每行tr中繪製7個td
四、在td中添加數字
五、用css區分這個月的日期數字和上個月或下個月的日期數字。
方法以下:
function drawTable(_year,_month) { table.innerHTML = ""; var allDayNum = getDateNum(_year,_month);//經過上面的方法得到了日期數組 var rows = allDayNum.length/7;//計算須要繪製多少行tr var index = 0;//日期數組的座標 for(var i=0;i<rows;i++){ var tr = document.createElement("tr"); for(var j=0;j<7;j++){//每行tr繪製7個td var td = document.createElement("td"); td.innerText = allDayNum[index].date;//在tr中填入數字 //若是是這個月的日期,讓其clss爲this-month(顏色加深) if(allDayNum[index].info==="this month"){ td.className="this-month" }else if(allDayNum[index].info==="today"){//若是日期爲今天,讓其顏色變紅。 td.className="today"; } tr.appendChild(td); index++; } table.appendChild(tr); } }
如何製做控制月份的控件?
方法以下:
//獲得頁面上的對象控件。 var preMontBtn = document.getElementById("pre-month"); var nextMontBtn = document.getElementById("next-mont"); //爲控件添加監聽事件 preMontBtn.addEventListener("click",function () { //得到頁面上顯示的年月 var dateInfo = { year:document.getElementById("table-year").innerText*1, month:document.getElementById("table-month").innerText*1 }; //計算上個月的年和月 var newDateInfo = { year:dateInfo.month-1===0?dateInfo.year-1:dateInfo.year, month:dateInfo.month-1===0?12:dateInfo.month-1 }; //修改頁面上的年月信息 document.getElementById("table-year").innerText = newDateInfo.year; document.getElementById("table-month").innerText = newDateInfo.month; //從新繪製表格,利用的是上文的方法 drawTable(newDateInfo.year,newDateInfo.month-1); }); //對下個月按鈕的監聽 nextMontBtn.addEventListener("click",function () { var dateInfo = { year:document.getElementById("table-year").innerText*1, month:document.getElementById("table-month").innerText*1 }; var newDateInfo = { year:dateInfo.month+1===13?dateInfo.year+1:dateInfo.year, month:dateInfo.month+1===13?1:dateInfo.month+1 }; document.getElementById("table-year").innerText = newDateInfo.year; document.getElementById("table-month").innerText = newDateInfo.month; drawTable(newDateInfo.year,newDateInfo.month-1); });
完整代碼在開篇。