到此為止我們已經(jīng)基本實(shí)現(xiàn)DateSelector類要提供的功能了,為了更靈活地控制它,我們應(yīng)該給它增加設(shè)定初始值的功能。一般來(lái)說(shuō)有兩種需求,第一種是傳入一個(gè)Date對(duì)象,第二種是傳入三個(gè)值分別表示年、月、日,也就是說(shuō)我們必須重載構(gòu)造函數(shù),形式如下:
function DateSelector(selYear, selMonth, selDay) function DateSelector(selYear, selMonth, selDay, date) function DateSelector(selYear, selMonth, selDay, year, month, day)
當(dāng)然,JavaScript沒(méi)有重載的概念,但我們可以給它模擬出來(lái),方法就是根據(jù)傳入?yún)?shù)的個(gè)數(shù)(即arguments對(duì)象的length)以及類型來(lái)判斷,這需要對(duì)原有的構(gòu)造函數(shù)進(jìn)行一定的改動(dòng)使之更模塊化地實(shí)現(xiàn)這三種情況。由于年份和月份是固定不變的,參數(shù)只會(huì)改變selYear和selMonth的已選選項(xiàng),而selDay則要根據(jù)selYear和selMonth的值再動(dòng)態(tài)生成,因此我們將初始化菜單代碼再提出來(lái)寫(xiě)一個(gè)InitSelector方法里,它有三個(gè)參數(shù),分別是year, month, day,功能是根據(jù)這三個(gè)參數(shù)來(lái)生成相應(yīng)的菜單選項(xiàng),我們這次調(diào)試使用2004年2月29日為初始值。要設(shè)置初始值的時(shí)候一般我們會(huì)循環(huán)訪問(wèn)option的值,但這里情況特殊,我們是可以根據(jù)一定的計(jì)算來(lái)得到默認(rèn)選擇的option的下標(biāo)的。
年份下標(biāo) = MaxYear - year 月份下標(biāo) = month - 1 天數(shù)下標(biāo) = day - 1
<html>
<head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312"> <title>如何實(shí)現(xiàn)一個(gè)日期下拉菜單</title> <script type="text/javascript"> function DateSelector(selYear, selMonth, selDay) { this.selYear = selYear; this.selMonth = selMonth; this.selDay = selDay; this.selYear.Group = this; this.selMonth.Group = this; // 給年份、月份下拉菜單添加處理onchange事件的函數(shù) if(window.document.all != null) // IE { this.selYear.attachEvent("onchange", DateSelector.Onchange); this.selMonth.attachEvent("onchange", DateSelector.Onchange); } else // Firefox { this.selYear.addEventListener("change", DateSelector.Onchange, false); this.selMonth.addEventListener("change", DateSelector.Onchange, false); }
if(arguments.length == 4) // 如果傳入?yún)?shù)個(gè)數(shù)為4,最后一個(gè)參數(shù)必須為Date對(duì)象 this.InitSelector(arguments[3].getFullYear(), arguments[3].getMonth() + 1, arguments[3].getDate()); else if(arguments.length == 6) // 如果傳入?yún)?shù)個(gè)數(shù)為6,最后三個(gè)參數(shù)必須為初始的年月日數(shù)值 this.InitSelector(arguments[3], arguments[4], arguments[5]); else // 默認(rèn)使用當(dāng)前日期 { var dt = new Date(); this.InitSelector(dt.getFullYear(), dt.getMonth() + 1, dt.getDate()); } }
// 增加一個(gè)最大年份的屬性 DateSelector.prototype.MinYear = 1900;
// 增加一個(gè)最大年份的屬性 DateSelector.prototype.MaxYear = (new Date()).getFullYear();
// 初始化年份 DateSelector.prototype.InitYearSelect = function() { // 循環(huán)添加OPION元素到年份select對(duì)象中 for(var i = this.MaxYear; i >= this.MinYear; i--) { // 新建一個(gè)OPTION對(duì)象 var op = window.document.createElement("OPTION"); // 設(shè)置OPTION對(duì)象的值 op.value = i; // 設(shè)置OPTION對(duì)象的內(nèi)容 op.innerHTML = i; // 添加到年份select對(duì)象 this.selYear.appendChild(op); } }
// 初始化月份 DateSelector.prototype.InitMonthSelect = function() { // 循環(huán)添加OPION元素到月份select對(duì)象中 for(var i = 1; i < 13; i++) { // 新建一個(gè)OPTION對(duì)象 var op = window.document.createElement("OPTION"); // 設(shè)置OPTION對(duì)象的值 op.value = i; // 設(shè)置OPTION對(duì)象的內(nèi)容 op.innerHTML = i; // 添加到月份select對(duì)象 this.selMonth.appendChild(op); } }
// 根據(jù)年份與月份獲取當(dāng)月的天數(shù) DateSelector.DaysInMonth = function(year, month) { var date = new Date(year, month, 0); return date.getDate(); }
// 初始化天數(shù) DateSelector.prototype.InitDaySelect = function() { // 使用parseInt函數(shù)獲取當(dāng)前的年份和月份 var year = parseInt(this.selYear.value); var month = parseInt(this.selMonth.value); // 獲取當(dāng)月的天數(shù) var daysInMonth = DateSelector.DaysInMonth(year, month); // 清空原有的選項(xiàng) this.selDay.options.length = 0; // 循環(huán)添加OPION元素到天數(shù)select對(duì)象中 for(var i = 1; i <= daysInMonth ; i++) { // 新建一個(gè)OPTION對(duì)象 var op = window.document.createElement("OPTION"); // 設(shè)置OPTION對(duì)象的值 op.value = i; // 設(shè)置OPTION對(duì)象的內(nèi)容 op.innerHTML = i; // 添加到天數(shù)select對(duì)象 this.selDay.appendChild(op); } }
// 處理年份和月份onchange事件的方法,它獲取事件來(lái)源對(duì)象(即selYear或selMonth) // 并調(diào)用它的Group對(duì)象(即DateSelector實(shí)例,請(qǐng)見(jiàn)構(gòu)造函數(shù))提供的InitDaySelect方法重新初始化天數(shù) // 參數(shù)e為event對(duì)象 DateSelector.Onchange = function(e) { var selector = window.document.all != null ? e.srcElement : e.target; selector.Group.InitDaySelect(); }
// 根據(jù)參數(shù)初始化下拉菜單選項(xiàng) DateSelector.prototype.InitSelector = function(year, month, day) { // 由于外部是可以調(diào)用這個(gè)方法,因此我們?cè)谶@里也要將selYear和selMonth的選項(xiàng)清空掉 // 另外因?yàn)镮nitDaySelect方法已經(jīng)有清空天數(shù)下拉菜單,因此這里就不用重復(fù)工作了 this.selYear.options.length = 0; this.selMonth.options.length = 0; // 初始化年、月 this.InitYearSelect(); this.InitMonthSelect(); // 設(shè)置年、月初始值 this.selYear.selectedIndex = this.MaxYear - year; this.selMonth.selectedIndex = month - 1; // 初始化天數(shù) this.InitDaySelect(); // 設(shè)置天數(shù)初始值 this.selDay.selectedIndex = day - 1; } </script> </head> <body> <select id="selYear"></select> <select id="selMonth"></select> <select id="selDay"></select> <script type="text/javascript"> var selYear = window.document.getElementById("selYear"); var selMonth = window.document.getElementById("selMonth"); var selDay = window.document.getElementById("selDay");
// 新建一個(gè)DateSelector類的實(shí)例,將三個(gè)select對(duì)象傳進(jìn)去 new DateSelector(selYear, selMonth ,selDay, 2004, 2, 29); // 也可以試試下邊的代碼 // var dt = new Date(2004, 1, 29); // new DateSelector(selYear, selMonth ,selDay, dt); </script> </body> </html>
好了,日期下拉菜單已經(jīng)能夠如我們想象的那樣開(kāi)始工作了,在調(diào)用的時(shí)候我們只需要執(zhí)行new DateSelector(selYear, selMonth ,selDay, 2004, 2, 29);就可以,而且它內(nèi)部關(guān)系緊密,你同一個(gè)頁(yè)面可以同時(shí)運(yùn)行好幾組日期下拉菜單而互不影響,這也是我要采用類的形式而不是采用一組函數(shù)來(lái)實(shí)現(xiàn)的緣由了,我以后寫(xiě)的文章也會(huì)盡可能采用類的形式,這樣寫(xiě)出來(lái)的代碼使用起來(lái)會(huì)更加方便。像以往一樣,我也得說(shuō)88啦,希望大家能夠繼續(xù)支持無(wú)憂腳本的原創(chuàng)文章,并且踴躍參與到其中來(lái)。
出處:藍(lán)色理想
責(zé)任編輯:moby
上一頁(yè) 實(shí)現(xiàn)一個(gè)日期下拉菜單 [2] 下一頁(yè)
◎進(jìn)入論壇網(wǎng)頁(yè)制作、網(wǎng)站綜合版塊參加討論
|