前言
方法是有參考網上一些資料的,比如閏年的判斷,比如每個月第一天是星期幾的判斷。不說太多,拆分出一個個函數,希望能描述盡可能的清晰明了。
一,判斷閏年
//判斷閏年 function runNian(_year) { if(_year%400 === 0 || (_year%4 === 0 && _year%100 !== 0) ) { return true; } else { return false; } }
二,判斷某年某月的1號是星期幾
//判斷某年某月的1號是星期幾 function getFirstDay(_year,_month) { var allDay = 0, y = _year-1, i = 1; allDay = y + Math.floor(y/4) - Math.floor(y/100) + Math.floor(y/400) + 1; for ( ; i<_month; i++) { switch (i) { case 1: allDay += 31; break; case 2: if(runNian(_year)) { allDay += 29; } else { allDay += 28; } break; case 3: allDay += 31; break; case 4: allDay += 30; break; case 5: allDay += 31; break; case 6: allDay += 30; break; case 7: allDay += 31; break; case 8: allDay += 31; break; case 9: allDay += 30; break; case 10: allDay += 31; break; case 11: allDay += 30; break; case 12: allDay += 31; break; } } return allDay%7; }
三,創建日歷表格,顯示日歷(表格應該在靜態頁面先寫好結構和樣式,然后在此處拼接,這里僅做示范,不附樣式)
//顯示日歷 function showCalendar(_year,_month,_day,firstDay) { var i = 0, monthDay = 0, showStr = "", _classname = "", today = new Date(); //月份的天數 switch(_month) { case 1: monthDay = 31; break; case 2: if(runNian(_year)) { monthDay = 29; } else { monthDay = 28; } break; case 3: monthDay = 31; break; case 4: monthDay = 30; break; case 5: monthDay = 31; break; case 6: monthDay = 30; break; case 7: monthDay = 31; break; case 8: monthDay = 31; break; case 9: monthDay = 30; break; case 10: monthDay = 31; break; case 11: monthDay = 30; break; case 12: monthDay = 31; break; } //輸出日歷表格,這部分因結構而異 showStr = "<table class='cld-w'><thead>"; //日歷頭部 showStr += "<tr><th colspan='7'><div class='cld-hd'><span class='cld-pre'><</span><em id='showDate' value='" + _year + "-" + _month + "-" + _day + "'>" + _year + "年" + _month + "月" + _day + "日" + "</em><span class='cld-next'>></span></div></th></tr>"; //日歷星期 showStr += "<tr><th>日</th><th>一</th><th>二</th><th>三</th><th>四</th><th>五</th><th>六</th></tr>"; showStr += "</thead><tbody><tr>"; //當月第一天前的空格 for (i=1; i<=firstDay; i++) { showStr += "<td></td>"; } //顯示當前月的天數 for (i=1; i<=monthDay; i++) { //當日的日期 if(_year === today.getFullYear() && _month === today.getMonth()+1 && i === today.getDate()) { _classname = "cld-cur"; } //當日之前的日期(這個判斷是因為我有工作需求,就是要求之前的日期不能點擊) else if(_year < today.getFullYear() || (_year === today.getFullYear() && _month <= today.getMonth()) || (_year === today.getFullYear() && _month === today.getMonth()+1 && i < today.getDate()) ) { _classname = "cld-old"; } //其他普通的日期 else { _classname = "cld-day"; } //其他大於當月的月份的相同日期(為了讓點擊下一月的時候,相同的日期增加cld-cur類) if(_day === i && (_year > today.getFullYear() || _month > today.getMonth()+1)) { _classname = "cld-cur"; } //把日期存在對應的value showStr += "<td class=" + _classname + " value='" + _year + "-" + _month + "-" + i + "'>" + i + "</td>"; firstDay = (firstDay+1)%7; if(firstDay === 0 && i !== monthDay) { showStr += "</tr><tr>"; } }
//剩余的空格 if(firstDay!==0) { for (i=firstDay; i<7; i++) { showStr += "<td></td>"; } } showStr +="</tr></tbody></table>"; //插入calendar的頁面結構里 calendar.innerHTML = showStr; }
四,在日歷的頭部顯示當前的年月日
//顯示年月日 function showDate(_year,_month,_day) { var date = "", firstDay = getFirstDay(_year,_month,_day); if(_day !== 0) { date = _year + "年" + _month + "月" +_day + "日"; } else { date = "No Choose."; } document.getElementById("showDate").innerHTML = date; //日歷頭部顯示 showCalendar(_year,_month,_day,firstDay); //調用日歷顯示函數 }
五,上一月和下一月
//上一月 function preMonth(_year,_month,_day) { if(_month == 1) { showDate(_year - 1,12,_day); } else { showDate(_year,_month - 1,_day); } } //下一月 function nextMonth(_year,_month,_day) { if(_month == 12) { showDate(_year + 1,1,_day); } else { showDate(_year,_month + 1,_day); } }
六,初始化,日歷就出來了
//初始化 var calendar = document.createElement('div'); calendar.setAttribute('id','showCld'); document.getElementById("box").appendChild(calendar); //增加到你的box里
//獲取當天的年月日 var today = new Date(); var _year = today.getFullYear(), _month = today.getMonth() + 1, _day = today.getDate(); var firstDay = getFirstDay(_year,_month);
//顯示日歷 showCalendar(_year,_month,_day,firstDay);
七,日歷的點擊事件
//日歷點擊的事件委托(可以查查js冒泡的應用) calendar.onclick = function(e) { var e = e || window.event; var target = e.srcElement || e.target; //把日歷的頭部的年月日分割成數組,這里保存在其value屬性上 dayArr = document.getElementById('showDate').getAttribute('value').split('-'); if (target) { //如果是可點擊的日期 if ( target.className === "cld-day" || target.className === "cld-cur" ) { dateArr = target.getAttribute('value').split('-'); //減0是把字符串轉化成數值類型,以下一樣
showDate(dateArr[0]-0,dateArr[1]-0,dateArr[2]-0); calendar.className = ""; } //如果是上一月的點擊 else if ( target.className === "cld-pre" ) { preMonth(dayArr[0]-0,dayArr[1]-0,dayArr[2]-0); } //如果是下一月的點擊 else if ( target.className === "cld-next" ) { nextMonth(dayArr[0]-0,dayArr[1]-0,dayArr[2]-0); } } };
——把解釋都寫着代碼里了,代碼函數比較簡單粗暴,沒辦法,本人對js繼承封裝還不熟呢。