国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

javascript設計模式--策略模式之輸入驗證

2019-11-20 11:08:42
字體:
來源:轉載
供稿:網友

策略模式定義了算法家族,分別封裝起來,讓他們之間可以互相替換,此模式讓算法的變化獨立于使用算飯的客戶.

先定義一個簡單的輸入表單:

<!DOCTYPE html><html>  <head>    <meta charset="utf-">    <style>      .form{        width: px;        height: px;        #margin: px auto;      }      .form-item-label{        width:px;        text-align: right;        float: left;      }      .form-item-input{        float: left;      }      .form-item{        width: % ;        height: px;        line-height: px;      }    </style>  </head>  <body>    <div class='form'>      <div class="form-item">        <div class='form-item-label'><span>用戶名:</span></div>        <div class='form-item-input'><input id='userName' name='用戶名' type="text"></div>      </div>      <div class="form-item" >        <div class='form-item-label'><span>密碼:</span></div>        <div class='form-item-input'><input id='password' name='密碼' type="text"></div>      </div>      <div class="form-item" >        <div class='form-item-label'><span>確認密碼:</span></div>        <div class='form-item-input'><input id='repassword' name='密碼確認' type="text"></div>      </div>      <div class="form-item" >        <div class='form-item-label'><span>郵箱:</span></div>        <div class='form-item-input'><input id='mail' name='郵箱' type="text" ></div>      </div>    </div>    <br>    <button id='submit' >提交</button>    <script type='text/javascript' src="../reference/jquery-...min.js"></script>  </body></html>

 一般在頁面上編輯信息后的提交動作中,都需要對輸入的信息進行驗證,會看到把很多負責check的代碼寫在提交函數中或者寫在一個獨立的check函數中。

比如像下面這樣。      

 $(document).ready(function(){        $('#submit').bind('click', doSubmit);      });      function doSubmit(){        var eleUserName = document.getElementById('userName');        if(eleUserName.value === '') {          alert('用戶名不能為空');          return;        }        if(eleUserName.length < 6) {          alert('用戶名長度不能少于6個字符');          return;        }        if(eleUserName.length > 6) {          alert('用戶名長度不能多于20個字符');          return;        }      }

這樣的寫法功能上肯定能滿足要求,但是,會存在幾個問題:

1.如果我要在其他頁面上使用,那就要將代碼進行復制,所謂的復用就變成了復制,代碼會存在大量重復。好一點的會把check代碼分類整理封裝,單還會存在較多的重復復制。

2.如果我要增加一個輸入驗證,那么就要直接修改提交函數,該函數會顯的臃腫,并且是破壞“開閉”原則的。

3.如果修改了提交函數,就要將函數設計的測試全都覆蓋一遍,因為,不知道何時就會發生誤改或者未知的情況。

改造步驟:

1.將每個驗證邏輯看成是一個驗證策略并封裝成每個驗證策略函數,函數參數保持一致,可以接受dom元素,被驗證的值,錯誤消息,定制參數。

2.定義驗證器,可將驗證策略函數導入,也可以添加。

3.驗證器提供驗證方法,用于驗證時的調用,其內部調用具體的驗證策略函數。

4.驗證調用。

步驟1.

把每一個if都看成一種校驗的業務規則,把每種業務規則作為一個單獨的策略函數,將所有的策略函數封裝成一個策略對象。       

 var validationStrategies = {        isNoEmpty: function(element, errMsg, value) {          if(value === '') {            return this.buildInvalidObj(element, errMsg, value );          }        },        minLength: function(element, errMsg, value, length) {          if(value.length < length){            return this.buildInvalidObj(element, errMsg, value);          }        },        maxLength: function(element, errMsg, value, length) {          if(value.length > length){            return this.buildInvalidObj(element, errMsg, value);          }        },        isMail: function(element, errMsg, value, length) {          var reg = /^(/w-*/.*)+@(/w-?)+(/./w{2,})+$/;          if(!reg.test(value)){            return this.buildInvalidObj(element, errMsg, value);          }        }      };

所有函數的參數的前3個都保持一致,而且是必須的,表示被驗證的DOM元素,錯誤消息,被驗證的值,第4個開始由函數自身的驗證規則決定定制的參數,可有多個參數。

“buildInvalidObj”方法只是把前3個參數打成一個錯誤對象進行返回,只要驗證不通過就會返回這個錯誤對象。

根據依賴倒置原則,高層次的模塊不應該依賴于低層次的模塊,因此不能讓驗證的調用方直接使用。

通過驗證器的方式進行封裝和抽象。

步驟2:

定義驗證器,可以將所有驗證策略導入其內,也可以單獨添加驗證策略函數。         

//輸入驗證器      function InputValidators(){        this.validators = [];        this.strategies = {};      }      //從策略對象導入驗證策略函數      //參數:      // strategies: 包含各種策略函數的對象      InputValidators.prototype.importStrategies = function(strategies) {        for(var strategyName in strategies) {          this.addValidationStrategy(strategyName, strategies[strategyName]);        }      };      //添加驗證策略函數      //參數:      // name: 策略名稱      // strategy: 策略函數      InputValidators.prototype.addValidationStrategy = function(name, strategy){        this.strategies[name] = strategy;      };

步驟3:

添加驗證方法,接受外部調用。

第一個參數rule,設置成驗證規則,比如 "minLength:6",通過下面的代碼會生成對具體策略函數的調用,調用會壓到緩存中,等待一起調用。

":6"表示策略函數根據自身規則所定制的參數。     

  //添加驗證方法      //參數:      // rule: 驗證策略字符串      // element: 被驗證的dom元素      // errMsg: 驗證失敗時顯示的提示信息      // value: 被驗證的值      InputValidators.prototype.addValidator = function(rule, element, errMsg, value) {        var that = this;        var ruleElements = rule.split(":");        this.validators.push(function() {          var strategy = ruleElements.shift();          var params = ruleElements;          params.unshift(value);          params.unshift(errMsg);          params.unshift(element);          return that.strategies[strategy].apply(that, params);        });      };

通過一個check函數來調用所有的驗證。并將錯誤的結果進行返回。      

   //開始驗證      InputValidators.prototype.check = function() {        for(var i = 0, validator; validator = this.validators[i++];){          var result = validator();          if(result) {            return result;          }        }      };

步驟4:

在需要驗證的地方,先new一個驗證器對象。              

var validators = new InputValidators();

將包含驗證策略函數的對象導入,或者單獨添加驗證策略函數。          

  validators.importStrategies(validationStrategies);        validators.addValidationStrategy('isEqual', function(element, errMsg, value1, value2) {          if(value1 !== value2) {            return this.buildInvalidObj(element, errMsg, value1 );          }        });

可以看出,不同的驗證策略我們可以預先封裝進策略對象中,也可以根據實際情況即時添加。

然后通過添加驗證方法將需要驗證的策略,被驗證的dom元素,錯誤消息,被驗證的值添加進驗證器中,這樣避免了直接調用策略對象,降低了耦合性。

var eleUserName = document.getElementById('userName');validators.addValidator('isNoEmpty', eleUserName, '用戶名不能為空', eleUserName.value);validators.addValidator('minLength:6', eleUserName, '用戶名的字符個數必須是6到20個', eleUserName.value);validators.addValidator('maxLength:20', eleUserName, '用戶名的字符個數必須是6到20個', eleUserName.value);var elePassword = document.getElementById('password');validators.addValidator('isNoEmpty', elePassword, '密碼不能為空', elePassword.value);validators.addValidator('minLength:6', elePassword, '密碼的字符個數必須是6到20個', elePassword.value);validators.addValidator('maxLength:20', elePassword, '密碼的字符個數必須是6到20個', elePassword.value);var eleRepassword = document.getElementById('repassword');validators.addValidator('isNoEmpty', eleRepassword, '確認密碼不能為空', eleRepassword.value);validators.addValidator('minLength:6', eleRepassword, '確認密碼的字符個數必須是6到20個', eleRepassword.value);validators.addValidator('maxLength:20', eleRepassword, '確認密碼的字符個數必須是6到20個', eleRepassword.value);validators.addValidator('isEqual:' + elePassword.value, eleRepassword, '兩次密碼不一致', eleRepassword.value);var eleMail = document.getElementById('mail');validators.addValidator('isNoEmpty', eleMail, '郵箱不能為空', eleMail.value);validators.addValidator('isMail', eleMail, '郵箱不是一個有效的格式', eleMail.value);

調用驗證器的check執行所有的驗證。            

var result = validators.check();        if(result){          alert(result.errMsg);          result.element.focus();          result.element.select();          return false;        }

check返回的是錯誤對象,我們可以在check后通過該對象統一地對DOM元素進行提示性操作,比如設置焦點,選中內容,或者為輸入框外部包上一層紅色的樣式。

至此,可以看出通過策略模式的改在,輸入驗證時,我們只需要關心用哪個驗證規則,采用什么樣的提示性信息即可,不再暴露實現細節,方便調用,方便后續的擴展和組件化。

全部代碼:

<!DOCTYPE html><html>  <head>    <meta charset="utf-8">    <style>      .form{        width: 400px;        height: 200px;        #margin: 0px auto;      }      .form-item-label{        width:100px;        text-align: right;        float: left;      }      .form-item-input{        float: left;      }      .form-item{        width: 100% ;        height: 50px;        line-height: 50px;      }    </style>  </head>  <body>    <div class='form'>      <div class="form-item">        <div class='form-item-label'><span>用戶名:</span></div>        <div class='form-item-input'><input id='userName' name='用戶名' type="text"></div>      </div>      <div class="form-item" >        <div class='form-item-label'><span>密碼:</span></div>        <div class='form-item-input'><input id='password' name='密碼' type="text"></div>      </div>      <div class="form-item" >        <div class='form-item-label'><span>確認密碼:</span></div>        <div class='form-item-input'><input id='repassword' name='密碼確認' type="text"></div>      </div>      <div class="form-item" >        <div class='form-item-label'><span>郵箱:</span></div>        <div class='form-item-input'><input id='mail' name='郵箱' type="text" ></div>      </div>    </div>    <br>    <button id='submit' >提交</button>    <script type='text/javascript' src="../reference/jquery-1.11.3.min.js"></script>    <script type='text/javascript'>      $(document).ready(function(){        $('#submit').bind('click', doSubmit);      });function doSubmit(){        var validators = new InputValidators();        validators.importStrategies(validationStrategies);        validators.addValidationStrategy('isEqual', function(element, errMsg, value1, value2) {          if(value1 !== value2) {            return this.buildInvalidObj(element, errMsg, value1 );          }        });        var eleUserName = document.getElementById('userName');        validators.addValidator('isNoEmpty', eleUserName, '用戶名不能為空', eleUserName.value);        validators.addValidator('minLength:6', eleUserName, '用戶名的字符個數必須是6到20個', eleUserName.value);        validators.addValidator('maxLength:20', eleUserName, '用戶名的字符個數必須是6到20個', eleUserName.value);        var elePassword = document.getElementById('password');        validators.addValidator('isNoEmpty', elePassword, '密碼不能為空', elePassword.value);        validators.addValidator('minLength:6', elePassword, '密碼的字符個數必須是6到20個', elePassword.value);        validators.addValidator('maxLength:20', elePassword, '密碼的字符個數必須是6到20個', elePassword.value);        var eleRepassword = document.getElementById('repassword');        validators.addValidator('isNoEmpty', eleRepassword, '確認密碼不能為空', eleRepassword.value);        validators.addValidator('minLength:6', eleRepassword, '確認密碼的字符個數必須是6到20個', eleRepassword.value);        validators.addValidator('maxLength:20', eleRepassword, '確認密碼的字符個數必須是6到20個', eleRepassword.value);        validators.addValidator('isEqual:' + elePassword.value, eleRepassword, '兩次密碼不一致', eleRepassword.value);        var eleMail = document.getElementById('mail');        validators.addValidator('isNoEmpty', eleMail, '郵箱不能為空', eleMail.value);        validators.addValidator('isMail', eleMail, '郵箱不是一個有效的格式', eleMail.value);        var result = validators.check();        if(result){          alert(result.errMsg);          result.element.focus();          result.element.select();          return false;        }        alert('驗證通過');      }      //輸入驗證器      function InputValidators(){        this.validators = [];        this.strategies = {};        //this.from(validationStrategies);      }      //添加驗證方法      //參數:      // rule: 驗證策略字符串      // element: 被驗證的dom元素      // errMsg: 驗證失敗時顯示的提示信息      // value: 被驗證的值      InputValidators.prototype.addValidator = function(rule, element, errMsg, value) {        var that = this;        var ruleElements = rule.split(":");        this.validators.push(function() {          var strategy = ruleElements.shift();          var params = ruleElements;          params.unshift(value);          params.unshift(errMsg);          params.unshift(element);          return that.strategies[strategy].apply(that, params);        });      };      //添加驗證策略函數      //參數:      // name: 策略名稱      // strategy: 策略函數      InputValidators.prototype.addValidationStrategy = function(name, strategy){        this.strategies[name] = strategy;      };      //從策略對象導入驗證策略函數      //參數:      // strategies: 包含各種策略函數的對象      InputValidators.prototype.importStrategies = function(strategies) {        for(var strategyName in strategies) {          this.addValidationStrategy(strategyName, strategies[strategyName]);        }      };      //驗證失敗時,將相關的錯誤信息打包返回      //參數:      // element: dom元素      //  errMsg: 驗證失敗時的提示消息      //  value: 被驗證的值      InputValidators.prototype.buildInvalidObj = function(element, errMsg, value){        return {          'value': value,          'element': element,          'errMsg': errMsg        };      };      //開始驗證      InputValidators.prototype.check = function() {        for(var i = 0, validator; validator = this.validators[i++];){          var result = validator();          if(result) {            return result;          }        }      };      //驗證策略對象,包含默認的驗證策略函數      var validationStrategies = {        isNoEmpty: function(element, errMsg, value) {          if(value === '') {            return this.buildInvalidObj(element, errMsg, value );          }        },        minLength: function(element, errMsg, value, length) {          if(value.length < length){            return this.buildInvalidObj(element, errMsg, value);          }        },        maxLength: function(element, errMsg, value, length) {          if(value.length > length){            return this.buildInvalidObj(element, errMsg, value);          }        },        isMail: function(element, errMsg, value, length) {          var reg = /^(/w-*/.*)+@(/w-?)+(/./w{2,})+$/;          if(!reg.test(value)){            return this.buildInvalidObj(element, errMsg, value);          }        }      };    </script>  </body></html>

以上所述是小編給大家介紹的javascript設計模式--策略模式之輸入驗證的全部內容,希望大家喜歡。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 潜山县| 宾川县| 松桃| 怀仁县| 类乌齐县| 昆明市| 古田县| 铁力市| 定日县| 沭阳县| 扶沟县| 屯留县| 呼伦贝尔市| 晴隆县| 天峻县| 阿克苏市| 常熟市| 扎兰屯市| 阳原县| 彝良县| 治县。| 望奎县| 内江市| 承德市| 贵溪市| 武功县| 阿鲁科尔沁旗| 托里县| 海林市| 灯塔市| 莱芜市| 谷城县| 泰和县| 呼玛县| 武山县| 深水埗区| 梓潼县| 辽宁省| 甘德县| 黄浦区| 舟山市|