Part 6 JavaScript – 月曆表格日期資料
在這個單元,我們要將實際的月曆填滿在安排好的表格上!
先備知識:
-
迴圈敘述 (for, while, do..while)
-
getElementsByTagName()方法
-
陣列物件
-
InnerHTML屬性
實現的邏輯(/做法/想法/構想/步驟/方法/演算法):
- 表格固定為6列x7行
- 計算出當月的第1天為禮拜幾
- 分成三部份填表
- 上個月後面幾天,用來填滿第一列前置的空白表格元素
- 當月,從1填到該月的最後1天 (會有一個陣列記錄每個月有幾天,並且當該年為閏年時,2月設定為29日。)
- 下個月的前幾天,用來填滿最後一列後面的空白表格元素
使用實際的程式語言具體實現上面的想法:
- PHP
- JavaScript
- C/C++/Object-C
- C#
- Java
- Basic
- ...
首先,我們先做個練習,將表格元素的內容以for迴圈填入0~41。
程式碼如下:(作法是利用document.getElementsByTagName("td")取得總共42(6x7)表格元素,再來填空!)
<script language="JavaScript"> updateDates(); //更新日期相關資料 //將月曆表格從1填到42 let days = document.getElementsByTagName("td"); //將td標籤放入days物件集合中 console.log(days.length); //利用console.log來檢視變數的值 for (var i = 0; i < days.length; i++){ days[i].innerHTML = i; } </script>
接著,我們先填這個月的1~最後1天:
作法是:
1.先計算出今年今月
2.建立今年今月1日的日期物件
3.利用這個物件算出今年今月1日是星期幾
//算出今年今月1日是星期幾 //先計算出今年今月 let today = new Date(); let thisYear = today.getFullYear(); let thisMonth = today.getMonth(); //建立今年今月1日的日期物件 let firstDayofMonth = new Date(thisYear, thisMonth, 1); //今年今月1日是星期幾 let weekDayofFirstDayofMonth = firstDayofMonth.getDay();
<script type="text/javascript" src="js/updateData.js" charset="utf-8"></script> <script language="JavaScript"> updateCalendar(); //將月曆表格從0填到41 let days = document.getElementsByTagName("td"); //將td標籤放入days物件集合中 var today = new Date(); var thisMonth = today.getMonth(); console.log(thisMonth); var thisYear = today.getFullYear(); var firstDateOfThisMonth = new Date(thisYear, thisMonth, 1);//建立今年今月1日的 Date日期物件 var firstDateDayOfThisMonth = firstDateOfThisMonth.getDay(); //取得今年今月1日是禮拜幾 // console.log(firstDateDayOfThisMonth); var monthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; //儲存每月的天數,其中2月為28或29 if ((thisYear % 4 == 0 && thisYear % 100 !=0) || (thisYear % 400 ==0)) monthDays[1]= 29; //若是閏年,2月設為29日 for (var i = 1; i <= monthDays[thisMonth]; i++){ //填今月日期在TD格子上,從今年今月1日是禮拜幾開始填1~今月天數 days[ firstDateDayOfThisMonth + i - 1].innerHTML = i; } </script>
20190409 課堂上的程式:
<script type="text/javascript" src="js/updateDateData.js"></script> <script language="JavaScript"> updateDateData(); let days = document.getElementsByTagName("td"); //將td標籤放入days物件集合中 var date = new Date(); var year = date.getFullYear(); var month = date.getMonth(); date = new Date(year, month, 1); weekDay = date.getDay(); //計算出今年今月1日是星期幾… var monthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; //每個月的天數 if ( ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0) ) monthDays[1] = 29; //閏年2月是29天 for (var i=weekDay, j=1; j <= monthDays[month]; i++, j++){ days[i].innerHTML = j; } </script>
課堂影音:
第一段
第二段
第三段
第四段
再來賸下前段與後段(是否清楚多了呢?):
- 前:days[0~weekDay-1]
- 後:days[weekDay + 這個月的天數 ~ 41]
這2個部份就當練習了!
2/22
填入日期上個月段:
加入程式碼:
for (var i = (weekDay-1), day = monthDays[curMonth-1]; i >=0; i--, day--){ days[i].innerHTML = day; }
填入日期下個月段:
for (var i = (weekDay+monthDays[curMonth]), day = 1; i <days.length; i++, day++){ days[i].innerHTML = day; }
填好資料的月曆畫面 (還有格式…)
<script language="JavaScript"> updateData(); //更新日期相關資料 var monthDays = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 32]; //第一個元素放個啞巴元素,好讓我們可以用1~12來存取月份的天數 var today = new Date(); var curYear = today.getFullYear(); var curMonth = today.getMonth() + 1; //函式傳回0~11,加個1符合我們的習慣 //判斷今年是否是閏 if ( ((curYear % 4 == 0) && (curYear % 100 != 0)) || (curYear % 400 == 0) ) monthDays[2] = 29; var weekDay = (new Date(curYear, curMonth,1)).getDay() ; //取得今年今月1日為禮拜幾 console.log(weekDay); var days = document.getElementsByTagName("td"); //中間段,當月 for (var i = 1; i <= monthDays[curMonth]; i++){ days[weekDay + i - 1].innerHTML = i; } //上個月段 for (var i = (weekDay-1), day = monthDays[curMonth-1]; i >=0; i--, day--){ days[i].innerHTML = day; } //下個月段 for (var i = (weekDay+monthDays[curMonth]), day = 1; i <days.length; i++, day++){ days[i].innerHTML = day; } </script>
updateData.js列表:
function getDayOfWeekName(day){ if (day == 0) return "Sunday"; if (day == 1) return "Monday"; if (day == 2) return "Tuesday"; if (day == 3) return "Wednesday"; if (day == 4) return "Thursday"; if (day == 5) return "Friday"; if (day == 6) return "Satday"; } function getMonthName(month){ if (month == 0) return "January"; if (month == 1) return "Feburary"; if (month == 2) return "March"; if (month == 3) return "April"; if (month == 4) return "May"; if (month == 5) return "June"; if (month == 6) return "July"; if (month == 7) return "August"; if (month == 8) return "September"; if (month == 9) return "October"; if (month == 10) return "November"; if (month == 11) return "December"; } function getOrdinary(date){ if (date == 1 || date == 21 || date == 31 ) return date + "<sup>st</sup>"; if (date == 2 || date == 22 ) return date + "<sup>nd</sup>"; if (date == 3 || date == 23 ) return date + "<sup>rd</sup>"; return date + "<sup>th</sup>"; } function updateCalendar(){ var today = new Date(); document.getElementById("cur-year").innerHTML = today.getFullYear(); document.getElementById("cur-month").innerHTML = getMonthName( today.getMonth() ); document.getElementById("cur-date").innerHTML = getOrdinary( today.getDate() ); document.getElementById("cur-day").innerHTML = getDayOfWeekName( today.getDay() ); document.getElementById("cal-year").innerHTML = today.getFullYear(); document.getElementById("cal-month").innerHTML = getMonthName( today.getMonth() ); fillInMonth(); } function fillInMonth(){ //將月曆表格從0填到41 let days = document.getElementsByTagName("td"); //將td標籤放入days物件集合中 var today = new Date(); var thisMonth = today.getMonth(); console.log(thisMonth); var thisYear = today.getFullYear(); var firstDateOfThisMonth = new Date(thisYear, thisMonth, 1);//建立今年今月1日的 Date日期物件 var firstDateDayOfThisMonth = firstDateOfThisMonth.getDay(); //取得今年今月1日是禮拜幾 // console.log(firstDateDayOfThisMonth); var monthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; //儲存每月的天數,其中2月為28或29 if ((thisYear % 4 == 0 && thisYear % 100 !=0) || (thisYear % 400 ==0)) monthDays[1]= 29; //若是閏年,2月設為29日 for (var i = 1; i <= monthDays[thisMonth]; i++){ //填今月日期在TD格子上,從今年今月1日是禮拜幾開始填1~今月天數 days[ firstDateDayOfThisMonth + i - 1].innerHTML = i; } //填上個月日期 for(var i = firstDateDayOfThisMonth - 1, d = monthDays[thisMonth - 1]; i >= 0; i--, d--) { // console.log(i + " ,,, " + d); days[i].innerHTML = d; } //填下個月日期 for(var i = firstDateDayOfThisMonth + monthDays[thisMonth], d = 1; i <= 41; i++, d++) { console.log(i + " ,,, " + d); days[i].innerHTML = d; } }
處理月曆表格"今天"的顯著背景(灰色底)
Study: DOM Element物件
背景色的處理,是在td上的元素指定id,透過css的current-day來進行格式設定:
<tr> <td>1</td> <td>1</td> <td>1</td> <td id="current-day">1</td> <td>1</td> <td>1</td> <td>1</td> </tr> <tr>
calendar.css中:
#calendar #current-day { background-color: #E1E1E1; }
我們用 document.getElementById找出指定id為current-day的td元素,並且將找出來的td元素去除掉這個id,
if (document.getElementById("current-day")) { document.getElementById("current-day").removeAttribute("id"); }
然後,使用setAttribute將今日的元素表格進行顯著設定:
//處理今日元素表格的顯著背景設定 if (document.getElementById("current-day")) { document.getElementById("current-day").removeAttribute("id"); } thisDate = today.getDate(); //取得今天的數字 days[firstDateDayOfThisMonth + thisDate - 1].setAttribute("id", "current-day");
接著設定上個月與下個月日期表格背景顏色
days[i].classList.add("color");
在設定顏色之前,先把整個表格的顏色設定去除掉。(利用classList.remove方法)
Study: classList物件成員說明與示範
var days = document.getElementsByTagName("td"); //下面迴圈將整個月曆表格元素去除掉color類別屬性,也就是把顏色的設定去掉。 for (let i = 0; i < days.length; i++){ if (days[i].classList.contains("color")) days[i].classList.remove("color"); } //中間段,當月 for (let i = 0; i < monthDays[calendarData.calendar.month]; i++){ days[weekDay + i].innerHTML = (i+1); } //上個月段 preMonth = calendarData.calendar.month-1; if (preMonth == 0) preMonth = 12; for (let i = (weekDay-1), day = monthDays[preMonth]; i >=0; i--, day--){ days[i].innerHTML = day; days[i].classList.add("color"); } //下個月段 for (let i = (weekDay+monthDays[calendarData.calendar.month]), day = 1; i <days.length; i++, day++){ days[i].innerHTML = day; days[i].classList.add("color"); }
目前階段的程式連結
參考資料: