[JavaScript] 得到某年某月的天數
這是 JavaScript 的一個作業的一部份,我把他拆成三個部份寫。這個部份是要在選擇某年某月之後,可以知道該月共有幾天,頁面操作上是有年的<select>標籤,選了年份後出現月的<select>標籤,選了月份後會出現日的<select>,而且日期的<option>必須符合該年該月,例如 2017 年 2 月有 28 天,最後一個的<option>就要 1 到 28:
這是 HTML 的樣子,其實三個<select>都在,只是月和日是隱藏的,在選擇年或月時才會顯示下一個:
<select id="seleYear"> </select> <select id="seleMonth" style="visibility: hidden;"> </select> <select id="seleDate" style="visibility: hidden;"> </select>
會用到 JavaScript 的 Date 物件,在上一篇 [JavaScript] 檢驗輸入日期是否真實存在 有筆記,下面快速介紹一次這次會用到的部份:
JavaScript 的 Date 物件
建構函式 new Date(Year, Month, Day):用年月日可建構代表該日期的物件,要注意 Month 是0 到 11,一月的 Month = 0,二月的 Month = 1,.... ,十二月的 Month = 11,所以 new Date( 2022, 1, 10 ) 會得到 2022 年 2 月 10 日的物件。
.getDate():回傳 Date 物件的日期,1日 = 1,2日 = 2,.... ,31日 = 31
上一篇有提到 Date 物件的推移情形,除了上一篇用來判斷日期是否存在,還可用來尋找當月的天數,因為月也可以推移,如果月 +1 會得下個月,而且跨年的情形也確實反映:
- new Date( 1985, 11, 18 ) 得 1985 年 12 月 18 日的物件
- new Date( 1985, 12, 18 ) 得 1986 年 1 月 18 日的物件
- new Date( 1985, 12, 1 ) 得 1986 年 1 月 1 日的物件
- new Date( 1985, 12, 0 ) 得 1985 年 12 月 31 日的物件
找出當年當月的天數
其實作法就是上面的兩張圖,利用月份 +1 得到下個月,將日期設為 1 則為下個月的第一天,日期設為 0 就回到這個月的最後一天,用.getDate() 就能取得這個月的總天數,其實還蠻容易的,下面把上述點選<select>標籤的程式碼貼一下:
var domYear = document.getElementById('seleYear'); // 取<select>標籤的DOM元素 var domMonth = document.getElementById('seleMonth'); var domDate = document.getElementById('seleDate'); domYear.addEventListener('change', generateMonth); // 註冊年與月的change事件 domMonth.addEventListener('change', generateDate); let docFrag = document.createDocumentFragment(); // 初始化填入<select>年份 let yearTitle = document.createElement('option'); yearTitle.setAttribute('value', 0); yearTitle.textContent = '年'; docFrag.appendChild(yearTitle); for (let i = 2010; i <= 2025; i++) { // 作業要求可以選擇 2010 年到 2025 年 let yearOption = document.createElement('option'); yearOption.setAttribute('value', i); yearOption.textContent = i; docFrag.appendChild(yearOption); } domYear.appendChild(docFrag); docFrag = document.createDocumentFragment(); // 初始化填入<select>月份 let monthTitle = document.createElement('option'); monthTitle.setAttribute('value', 0); monthTitle.textContent = '月'; docFrag.appendChild(monthTitle); for (let i = 1; i <= 12; i++) { // 月份可選擇 1 月到 12 月 let monthOption = document.createElement('option'); monthOption.setAttribute('value', i); monthOption.textContent = i; docFrag.appendChild(monthOption); } domMonth.appendChild(docFrag); function generateMonth() { // 年份<select>值改變時觸發 if (domYear.value == 0) { return; } domDate.style.visibility = 'hidden'; // 隱藏日期<select> domMonth.style.visibility = 'visible'; // 顥示月份<select> } function generateDate() { // 月份<select>值改變時觸發 if (domMonth.value == 0) { return; } let selectY = domYear.value; let selectM = domMonth.value - 1; // select 選到的月份要 -1 才是 date 物件裡的月 let totalDate = new Date(selectY, selectM + 1, 0).getDate(); // +1推下一個月,日期0則退1天,得到當月最後一天 domDate.style.visibility = 'visible'; domDate.innerHTML = ''; let docFrag = document.createDocumentFragment(); let dateTitle = document.createElement('option'); dateTitle.setAttribute('value', 0); dateTitle.textContent = '日'; docFrag.appendChild(dateTitle); for (let i = 1; i <= totalDate; i++) { // 產生 1 到 totalDate 的<option> let dateOption = document.createElement('option'); dateOption.setAttribute('value', i); dateOption.textContent = i; docFrag.appendChild(dateOption); } domDate.appendChild(docFrag); }
留言
張貼留言