表單驗證中時間起止判斷的遞歸處理
在最近一個項目中,表單驗證需要對時間的起止范圍進行判斷:結(jié)束時間需大于或等于開始時間。即:結(jié)束年須大于起始年;如果相等,則比較起始月與結(jié)束月;如果起止月也相等,則比較日期。那么,對于每一次驗證,可以用下面這個函數(shù)來進行比較。
function compare(begin,end,error){ var begin = parseInt(begin,10); var end = parseInt(end,10); var diff = end - begin; if(diff < 0){ alert(error); }else{ return true; } }
這樣,在驗證的時候,只要結(jié)果返回真就表示通過。如:
var year = compare(2001,2003,'年'); var month = compare(1,2,'月'); var day = compare(12,13,'天'); alert(year && month && day); //結(jié)果為真------"true"
將上面的起止月份和起止日期修改一下。如:
var year = compare(2001,2003,'年'); var month = compare(3,2,'月'); var day = compare(24,13,'天'); alert(year && month && day); /結(jié)果為假------"false"
執(zhí)行結(jié)果,依次顯示”月”,”天”,”false”;實際上,當起止月份不正確的時候,我們沒必要對日期進行驗證;月份驗證的前提條件是年驗證通過;天驗證的前提是月份驗證通過。仔細分析之后,我決定將上面函數(shù)的三個參數(shù)用單體模式存儲起來,即:
{ begin:2001, end:2003, error:"結(jié)束年限須大于起始年限" }
但是,我又不想定義函數(shù)的參數(shù),函數(shù)能否根據(jù)傳遞的參數(shù)自動進行驗證了?答案是肯定的。在函數(shù)的開始,先判斷參數(shù)的個數(shù),如果大于1,則含有遞歸處理。如何做到遞歸處理呢?我在函數(shù)內(nèi)部作了如下處理:
var len = arguments.length; if(len > 1){ var args = Array.prototype.slice.call(arguments); args.shift(); //將第一個參數(shù)移除,余下的用作遞歸處理的參數(shù) }
對于arguments,我們不能直接調(diào)用Array.shift()方法。雖然 arguments有l(wèi)ength屬性,但畢竟不是數(shù)組,所以用Array.slice()方法將其轉(zhuǎn)換成數(shù)組。關于arguments,在網(wǎng)上可以了解到更多的信息,這里不在贅述。為什么只有在len大于1時才進行處理呢?因為參數(shù)為1時,就不需要進行下一步驗證了。遞歸處理在什么時候進行呢?仔細想想,只有在初始值與結(jié)束值相等時才需要,明白了這些,我們就很容易構(gòu)建我們的驗證函數(shù)了。
var diff = parseInt(arguments[0].end,10) - parseInt(arguments[0].begin,10); if(diff <0 ){ alert(arguments[0].error); return false; }else if(diff == 0){ return len > 1 ? arguments.callee.apply(this,args) : true; }else{ return true; }
上面的代碼中,arguments.callee是函數(shù)自身,關于apply的用法可以在web查找相關資料。
function compare(){ var len = arguments.length; if(len > 1){ var args = Array.prototype.slice.call(arguments); args.shift(); //將第一個參數(shù)移除,余下的用作遞歸處理的參數(shù)
} var diff = parseInt(arguments[0].end,10) - parseInt(arguments[0].begin,10); if(diff <0 ){ alert(arguments[0].error); return false; }else if(diff == 0){ return len > 1 ? arguments.callee.apply(this,args) : true; }else{ return true; } }
到此驗證函數(shù)已經(jīng)完成,但需要注意的是:
- 雖然沒有確定參數(shù)的個數(shù),但參數(shù)的順序還是重要的,因為前一個參數(shù)的驗證結(jié)果決定了下一個參數(shù)的驗證是否繼續(xù);
- parseInt()函數(shù)的第二個參數(shù)10不要忽略。如果忽略,當遇到以0開始的數(shù)值(如07、08)時將會按八進制進行處理。
到此已經(jīng)結(jié)束,看看 示例 。有時候,我們不想以alert的方式顯示錯誤信息,我們可以自定義處理函數(shù)將其作為最后一個參數(shù)傳入其中。那么在函數(shù)的開始,取得處理函數(shù),如:
var func = arguments[len - 1]; if(typeof func == 'function'){ func(arguments[0]); }
所以,最終的處理函數(shù)是這樣的:
function compare(){ var len = arguments.length; var func = arguments[len - 1]; if(len > 1){ var args = Array.prototype.slice.call(arguments); args.shift(); //將第一個參數(shù)移除,余下的用作遞歸處理的參數(shù) } var diff = parseInt(arguments[0].end,10) - parseInt(arguments[0].begin,10); if(diff <0 ){ (typeof func == 'function') ? func(arguments[0].error) : alert(arguments[0].error); return false; }else if(diff == 0){ return len > 1 ? arguments.callee.apply(this,args) : true; }else{ return true; } }
原文:http://www.denisdeng.com/?p=631
本文鏈接:http://www.95time.cn/tech/web/2009/7270.asp
出處:藍色理想
責任編輯:bluehearts
◎進入論壇網(wǎng)頁制作、WEB標準化版塊參加討論,我還想發(fā)表評論。
|