0 源起
上周末,大寶發現今年自己的生日不是周末,這樣就不好約同學和好友一起開生日Party了,很是郁悶。一直嘀咕自己哪年的生日才是周末。
于是我用JavaScript寫了一個小程序來幫她測算了未來100年中每年的生日分別是星期幾。
1 設計交互界面
用一個文本框來輸入年份,
一個下拉列表框來選擇月份,
一個下拉列表框來選擇日,
一個按鈕來進行測算,
一個多行文本輸入框來顯示測算結果。
<p>你的生日是星期幾?</p>
<p>請輸入生日信息</p>
<input type="text" id="txtYear" value="2024">年<select id="lsbMonth"></select>月<select id="lsbDay"></select>日
<input type="button" value="測算" id="btnCheck">
<p><textarea id="taResult" rows="15" cols="60"></textarea></p>
主打簡潔,如下圖:
2 輸入控制
2.1 年份文本框只允輸入4位整數
?當用戶修改年份文本框中的內容,導致文本框的值發生改變時,會觸發oninput事件,我們對這個事件進行處置,只允許輸入數字,并且只保留前4位數字。
//年份輸入處理
function txtYear_onInput()
{var a = txtYear.value.replace(/[^\d]/g,'');//只允許輸入數字txtYear.value = a.substr(0,4);//只允許四位數字
} // txtYear_onInput()txtYear.oninput = function() {txtYear_onInput()};
2.2?月份列表框
一年12個月,用一個函數來填充其值。
//初始化月份
function lsbMonth_Init()
{for (var i=1;i<13; i++){lsbMonth.options[i-1] = new Option(i, i, true, true); }lsbMonth.selectedIndex = 0;
}//lsbMonth_Init();lsbMonth_Init();
2.3?日列表框
每年的1月、3月、5月、7月、8月、10月、12月是31天。
每年的14月、6月、9月、11月是30天。
2月特殊一些,平年是28天,閏年是29天。
我們先初始化日列表框為31天。
//初始化“日”下拉列表框
function lsbDay_Init()
{for (var i = 0;i < 31; i++){lsbDay.options[i] = new Option(i+1,i+1,true,true);}lsbDay.selectedIndex = 0;
}//lsbDay_Init();lsbDay_Init();
當用戶修改年份時,會觸發onchange事件,
當用戶修改月份時,也會觸發onchange事件,
我們對這兩個事件進行處理:
- 先獲取年份和月份的值,
- 如果用戶選擇的是2月,就判斷用戶選擇的年份是平年還是閏年,平年就是28天,閏年就29天。
- 如果用戶選擇的是1月、3月、5月、7月、8月、10月或12月,那么就是31天,否則就是30天。
- 根據測算出來的天數調整日列表框的值。
//獲取年份
function txtYear_getYear()
{return txtYear.value;//return document.getElementById("txtYear").value;
}
//alert(txtYear_getYear())//獲取月份
function lsbMonth_getMonth()
{return lsbMonth.options[lsbMonth.selectedIndex].value;
}//判斷是否為閏年
function isLeapYear(y)
{return (y % 4 == 0 && y % 100 !=0 || y % 400 == 0);
}//根據用戶輸入的年份和月份,動態調整“日”下拉列表框的內容
function lsbDay_Adjust()
{var s = lsbDay.selectedIndex;//alert('typeof s='+ typeof(s)+ ' s='+s);var y = txtYear_getYear();//alert('y='+y);if (y <= 0){alert("請先輸入年份");return;}var m = lsbMonth_getMonth();//alert('m='+ m);var d;if (2==m){d = isLeapYear(y) ? 29 : 28;}else{d = (m==1 || m==3 || m==5 | m==7 || m==8 || m==10 || m==12 ? 31 : 30); }//alert('d='+d);lsbDay.options.length = d;//alert('lsbDay.options.length='+lsbDay.options.length);for (var i = 0;i < d; i++){lsbDay.options[i] = new Option(i+1,i+1,true,true);}lsbDay.selectedIndex = s < d ? s : 0;
}//lsbDay_Adjust();txtYear.oninput = function() {txtYear_onInput()};txtYear.onchange = function() {lsbDay_Adjust()};
2.4?測算按鈕
獲取年月日數值,使用日期對象的getFullYear() 方法生成一個日期,然用利用日期對象的getDay() 方法返回指定日期是星期幾,把結果填入測算結果。
btnCheck.onclick = function(){checkDay()};function lsbDay_getDay()
{return lsbDay.options[lsbDay.selectedIndex].value;
}function checkDay()
{var a = new Date();var y = txtYear_getYear(), m = lsbMonth_getMonth(), d = lsbDay_getDay();var w, s, r = '';for (var i=0;i < 100;i++){a.setFullYear(y*1+i ,m-1,d);w = a.getDay();s = '';//alert(a);r += a.getFullYear() + '年' + m + '月' + d + '日 是 星期' + "日一二三四五六".charAt(w) + '\n';} //fortaResult.value = r;
}
3?一些改進思路
1.初始化年月日時將默認值?設置系統當前日期
2.可以使用?date輸入框:
<input type="date" value="2024-06-01">
3.使用<iframe>代替<textarea>,對周日——周六分別用不同的顏色來顯示。
?
4.用戶界面上可以加上一個生日蛋糕之類的圖片烘托氛圍。