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(6×7)表格元素,再來填空!)
<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");
}
目前階段的程式連結
參考資料:








