眾所周知的是,表單確實在前端,唔,或者說在網頁中占有不小的比重。事實上,幾乎每一個中大型網站都會有“登錄注冊”以驗證用戶信息、防止一些不可名狀的隱患。。。
那么表單的優劣就成了前端開發者急需解決的問題。其實我更愿意稱為“代碼的可讀性”或“可復用性”以及“是否冗雜”。
表單也有“優劣”?你在開玩笑嘛?
我想你可以認真看下下面的代碼,它用到了一些“新知識”:
1
2
3
4
5
6
|
<form action= "xxx" id= "registerForm" > 請輸入用戶名:<input type= "text" name= "userName" id= "name" /> 請輸入密碼:<input type= "text" name= "password" id= "pass" /> 請輸入手機號:<input type= "text" name= "phoneNumber" id= "phone" /> <button>提交</button> </form> |
用戶名、密碼、手機號這應該是表單中最常見的了,好,我們就以此分析!
上面這些只是簡單的演示效果,你完全可以用css的valid/invalid、HTML5的required/pattern來配合完成。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<script> var registerForm=document.getElementById( 'registerForm' ) registerForm.onsubmit= function (){ if (registerForm.userName.value== '' ){ document.getElementById( "name" ).setCustomValidity( '用戶名不能為空' ); return false ; } if (registerForm.password.value.length<6){ document.getElementById( "pass" ).setCustomValidity( '密碼長度不能少于6位' ); return false ; } if (!/(^1[3|5|8][0-9]{9}$)/.test(registerForm.phoneNumber.value)){ document.getElementById( "phone" ).setCustomValidity( '手機號碼格式不正確' ); return false ; } } </script> |
但即使這樣,你也不會覺得它很完美 —— 現在表單只有三條,如果某一天它增加到了N條,即使是「復制粘貼」也拯救不了你!
就在這時,你想到了 策略模式 (看,JS總是會讓你“靈光一現”)
說起策略模式,很自然地,要遵循 暴露接口和實現邏輯分離 的原則。
策略模式指的是定義一系列的算法,把它們一個個封裝起來。將不變的部分和變化的部分隔開是每個設計模式的主題,策略模式也不例外,
策略模式的目的就是將算法的使用與算法的實現分離開來。
一個基于策略模式的程序至少由兩部分組成。第一個部分是一組策略類,策略類封裝了具體的算法,并負責具體的計算過程。第二個部分是環境類 Context,Context 接受客戶的請求,隨后把請求委托給某一個策略類。要做到這點,說明 Context 中要維持對某個策略對象的引用
——《JavaScript設計模式與開發實踐》
那么,第一步我們很顯然要把這些校驗邏輯都封裝成【策略對象】:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
var strategies={ isNoneEmpty: function (value,errorMsg){ if (value=== '' ){ return errorMsg; } }, minLength: function (value,length,errorMsg){ if (value.length<length){ return errorMsg; } }, isMobile: function (value,errorMsg){ if (!/(^1[3|5|8][0-9]{9}$)/.test(value)){ return errorMsg; } } }; |
接下來我們要實現一個“暴露出去的”、“作為調用的”方法類 —— 它將作為context(上下文),負責接收用戶的請求并委托給驗證對象stratrgies:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
var Validator= function (){ this .cache=[]; //用于保存接收到的校驗規則 }; Validator.prototype.add= function (dom,rule,errorMsg){ var ary=rule.split( ':' ); this .cache.push( function (){ var strategy=ary.shift(); ary.unshift(dom.value); ary.push(errorMsg); return strategies[strategy].apply(dom,ary); //調用strategies對象的指定方法對象,并規定在函數對象內部this指向dom元素,ary作為參數傳入 }); }; Validator.prototype.start= function (){ for ( var i=0,validatorFunc;validatorFunc= this .cache[i++];){ var msg=validatorFunc(); if (msg){ return msg; } } } |
使用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
var validataFunc= function (){ var validator= new Validator(); //添加校驗規則 validator.add(registerForm.userName, 'isNoneEmpty' , '用戶名不能為空' ); validator.add(registerForm.password, 'minLength:6' , '密碼長度不能少于6位' ); validator.add(registerForm.phoneNumber, 'isMobile' , '手機號碼格式不正確' ); var errMsg=validator.start(); //獲得校驗結果 return errorMsg; //返回 } var registerForm=document.getElementById( 'registerForm' ) registerForm.onsubmit= function (){ var errorMsg=validataFunc(); if (errorMsg){ //觸發錯誤提示 return false ; //并阻止表單提交 } } |
我們可以看到的是:當我們往 validator 對象里添加完一系列的校驗規則之后,會調用 validator.start()
方法來啟動校驗。如果 validator.start()
返回了一個確切的 errorMsg 字符串當作返回值,說明該次校驗沒有通過,此時需讓 registerForm.onsubmit
方法返回 false 來阻止表單的提交。
這樣確實比之前好很多:至少在我們修改驗證規則時顯得毫不費力:
1
|
validator.add(registerForm.userName, 'minLength:2' , '用戶名不能少于2位' ) |
但是問題也就隨之而來了:我們把對于用戶名的驗證規則“不能為空”改為了“不能少于兩位”,那么就不能驗證“是否為空”了。
能不能像element-ui一樣可以自定義多種驗證規則 呢?就像這樣:
1
2
3
4
5
6
7
|
validator.add(registerForm.userName,[{ strategy: 'isNoneEmpty' , errorMsg: '用戶名不能為空' },{ strategy: 'minLength:2' , errorMsg: '用戶名長度不能少于2位' }]) |
現在“rule”是數組-對象的形式了,我們需要把add函數改一下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
Validator.prototype.add= function (dom,rules){ var self= this ; for ( var i=0,rule;rule=rules[i++];){ ( function (rule){ var strategyAry=rule.strategy.split( ':' ); var errorMsg=rule.errorMsg; self.cache.push( function (){ var strategy=strategyAry.shift(); strategyAry.unshift(dom.value); return strategies[strategy].apply(dom,strategyAry); }); })(rule) } } |
策略模式的優點:
利用組合、委托、多態等技術和思想,可以有效地避免多重條件選擇語句(關于這一點,筆者在 這篇文章 中做了詳細說明);完美實現了設計模式都應該具有的“對外開放-封閉”原則,基于策略模式實現的規則大多易于擴展、易于使用避免了大量CV的工作
到此這篇關于從表單校驗看JavaScript策略模式的使用詳解的文章就介紹到這了,更多相關JavaScript策略模式使用內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://blog.csdn.net/qq_43624878/article/details/107934317