欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

javascript設(shè)計(jì)模式--策略模式之輸入驗(yàn)證

 更新時(shí)間:2015年11月27日 14:31:10   作者:白色的海  
策略模式中的策略就是一種算法或者業(yè)務(wù)規(guī)則,將這些策略作為函數(shù)進(jìn)行封裝,并向外提供統(tǒng)一的調(diào)用執(zhí)行,本文給大家介紹javascript設(shè)計(jì)模式--策略模式之輸入驗(yàn)證,需要的朋友參考下

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

先定義一個(gè)簡單的輸入表單:

<!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>確認(rèn)密碼:</span></div>
        <div class='form-item-input'><input id='repassword' name='密碼確認(rèn)' 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>

 一般在頁面上編輯信息后的提交動作中,都需要對輸入的信息進(jìn)行驗(yàn)證,會看到把很多負(fù)責(zé)check的代碼寫在提交函數(shù)中或者寫在一個(gè)獨(dú)立的check函數(shù)中。

比如像下面這樣。      

 $(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個(gè)字符');
          return;
        }
        if(eleUserName.length > 6) {
          alert('用戶名長度不能多于20個(gè)字符');
          return;
        }
      }

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

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

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

3.如果修改了提交函數(shù),就要將函數(shù)設(shè)計(jì)的測試全都覆蓋一遍,因?yàn)椋恢篮螘r(shí)就會發(fā)生誤改或者未知的情況。

改造步驟:

1.將每個(gè)驗(yàn)證邏輯看成是一個(gè)驗(yàn)證策略并封裝成每個(gè)驗(yàn)證策略函數(shù),函數(shù)參數(shù)保持一致,可以接受dom元素,被驗(yàn)證的值,錯(cuò)誤消息,定制參數(shù)。

2.定義驗(yàn)證器,可將驗(yàn)證策略函數(shù)導(dǎo)入,也可以添加。

3.驗(yàn)證器提供驗(yàn)證方法,用于驗(yàn)證時(shí)的調(diào)用,其內(nèi)部調(diào)用具體的驗(yàn)證策略函數(shù)。

4.驗(yàn)證調(diào)用。

步驟1.

把每一個(gè)if都看成一種校驗(yàn)的業(yè)務(wù)規(guī)則,把每種業(yè)務(wù)規(guī)則作為一個(gè)單獨(dú)的策略函數(shù),將所有的策略函數(shù)封裝成一個(gè)策略對象。       

 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);
          }
        }
      };

所有函數(shù)的參數(shù)的前3個(gè)都保持一致,而且是必須的,表示被驗(yàn)證的DOM元素,錯(cuò)誤消息,被驗(yàn)證的值,第4個(gè)開始由函數(shù)自身的驗(yàn)證規(guī)則決定定制的參數(shù),可有多個(gè)參數(shù)。

“buildInvalidObj”方法只是把前3個(gè)參數(shù)打成一個(gè)錯(cuò)誤對象進(jìn)行返回,只要驗(yàn)證不通過就會返回這個(gè)錯(cuò)誤對象。

根據(jù)依賴倒置原則,高層次的模塊不應(yīng)該依賴于低層次的模塊,因此不能讓驗(yàn)證的調(diào)用方直接使用。

通過驗(yàn)證器的方式進(jìn)行封裝和抽象。

步驟2:

定義驗(yàn)證器,可以將所有驗(yàn)證策略導(dǎo)入其內(nèi),也可以單獨(dú)添加驗(yàn)證策略函數(shù)。         

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

步驟3:

添加驗(yàn)證方法,接受外部調(diào)用。

第一個(gè)參數(shù)rule,設(shè)置成驗(yàn)證規(guī)則,比如 "minLength:6",通過下面的代碼會生成對具體策略函數(shù)的調(diào)用,調(diào)用會壓到緩存中,等待一起調(diào)用。

":6"表示策略函數(shù)根據(jù)自身規(guī)則所定制的參數(shù)。     

  //添加驗(yàn)證方法
      //參數(shù):
      // rule: 驗(yàn)證策略字符串
      // element: 被驗(yàn)證的dom元素
      // errMsg: 驗(yàn)證失敗時(shí)顯示的提示信息
      // value: 被驗(yàn)證的值
      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);
        });
      };

通過一個(gè)check函數(shù)來調(diào)用所有的驗(yàn)證。并將錯(cuò)誤的結(jié)果進(jìn)行返回。      

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

步驟4:

在需要驗(yàn)證的地方,先new一個(gè)驗(yàn)證器對象。              

var validators = new InputValidators();

將包含驗(yàn)證策略函數(shù)的對象導(dǎo)入,或者單獨(dú)添加驗(yàn)證策略函數(shù)。          

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

可以看出,不同的驗(yàn)證策略我們可以預(yù)先封裝進(jìn)策略對象中,也可以根據(jù)實(shí)際情況即時(shí)添加。

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

var eleUserName = document.getElementById('userName');
validators.addValidator('isNoEmpty', eleUserName, '用戶名不能為空', eleUserName.value);
validators.addValidator('minLength:6', eleUserName, '用戶名的字符個(gè)數(shù)必須是6到20個(gè)', eleUserName.value);
validators.addValidator('maxLength:20', eleUserName, '用戶名的字符個(gè)數(shù)必須是6到20個(gè)', eleUserName.value);
var elePassword = document.getElementById('password');
validators.addValidator('isNoEmpty', elePassword, '密碼不能為空', elePassword.value);
validators.addValidator('minLength:6', elePassword, '密碼的字符個(gè)數(shù)必須是6到20個(gè)', elePassword.value);
validators.addValidator('maxLength:20', elePassword, '密碼的字符個(gè)數(shù)必須是6到20個(gè)', elePassword.value);
var eleRepassword = document.getElementById('repassword');
validators.addValidator('isNoEmpty', eleRepassword, '確認(rèn)密碼不能為空', eleRepassword.value);
validators.addValidator('minLength:6', eleRepassword, '確認(rèn)密碼的字符個(gè)數(shù)必須是6到20個(gè)', eleRepassword.value);
validators.addValidator('maxLength:20', eleRepassword, '確認(rèn)密碼的字符個(gè)數(shù)必須是6到20個(gè)', 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, '郵箱不是一個(gè)有效的格式', eleMail.value);

調(diào)用驗(yàn)證器的check執(zhí)行所有的驗(yàn)證。            

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

check返回的是錯(cuò)誤對象,我們可以在check后通過該對象統(tǒng)一地對DOM元素進(jìn)行提示性操作,比如設(shè)置焦點(diǎn),選中內(nèi)容,或者為輸入框外部包上一層紅色的樣式。

至此,可以看出通過策略模式的改在,輸入驗(yàn)證時(shí),我們只需要關(guān)心用哪個(gè)驗(yàn)證規(guī)則,采用什么樣的提示性信息即可,不再暴露實(shí)現(xiàn)細(xì)節(jié),方便調(diào)用,方便后續(xù)的擴(kuò)展和組件化。

全部代碼:

<!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>確認(rèn)密碼:</span></div>
        <div class='form-item-input'><input id='repassword' name='密碼確認(rèn)' 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, '用戶名的字符個(gè)數(shù)必須是6到20個(gè)', eleUserName.value);
        validators.addValidator('maxLength:20', eleUserName, '用戶名的字符個(gè)數(shù)必須是6到20個(gè)', eleUserName.value);
        var elePassword = document.getElementById('password');
        validators.addValidator('isNoEmpty', elePassword, '密碼不能為空', elePassword.value);
        validators.addValidator('minLength:6', elePassword, '密碼的字符個(gè)數(shù)必須是6到20個(gè)', elePassword.value);
        validators.addValidator('maxLength:20', elePassword, '密碼的字符個(gè)數(shù)必須是6到20個(gè)', elePassword.value);
        var eleRepassword = document.getElementById('repassword');
        validators.addValidator('isNoEmpty', eleRepassword, '確認(rèn)密碼不能為空', eleRepassword.value);
        validators.addValidator('minLength:6', eleRepassword, '確認(rèn)密碼的字符個(gè)數(shù)必須是6到20個(gè)', eleRepassword.value);
        validators.addValidator('maxLength:20', eleRepassword, '確認(rèn)密碼的字符個(gè)數(shù)必須是6到20個(gè)', 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, '郵箱不是一個(gè)有效的格式', eleMail.value);
        var result = validators.check();
        if(result){
          alert(result.errMsg);
          result.element.focus();
          result.element.select();
          return false;
        }
        alert('驗(yàn)證通過');
      }
      //輸入驗(yàn)證器
      function InputValidators(){
        this.validators = [];
        this.strategies = {};
        //this.from(validationStrategies);
      }
      //添加驗(yàn)證方法
      //參數(shù):
      // rule: 驗(yàn)證策略字符串
      // element: 被驗(yàn)證的dom元素
      // errMsg: 驗(yàn)證失敗時(shí)顯示的提示信息
      // value: 被驗(yàn)證的值
      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);
        });
      };
      //添加驗(yàn)證策略函數(shù)
      //參數(shù):
      // name: 策略名稱
      // strategy: 策略函數(shù)
      InputValidators.prototype.addValidationStrategy = function(name, strategy){
        this.strategies[name] = strategy;
      };
      //從策略對象導(dǎo)入驗(yàn)證策略函數(shù)
      //參數(shù):
      // strategies: 包含各種策略函數(shù)的對象
      InputValidators.prototype.importStrategies = function(strategies) {
        for(var strategyName in strategies) {
          this.addValidationStrategy(strategyName, strategies[strategyName]);
        }
      };
      //驗(yàn)證失敗時(shí),將相關(guān)的錯(cuò)誤信息打包返回
      //參數(shù):
      // element: dom元素
      //  errMsg: 驗(yàn)證失敗時(shí)的提示消息
      //  value: 被驗(yàn)證的值
      InputValidators.prototype.buildInvalidObj = function(element, errMsg, value){
        return {
          'value': value,
          'element': element,
          'errMsg': errMsg
        };
      };
      //開始驗(yàn)證
      InputValidators.prototype.check = function() {
        for(var i = 0, validator; validator = this.validators[i++];){
          var result = validator();
          if(result) {
            return result;
          }
        }
      };
      //驗(yàn)證策略對象,包含默認(rèn)的驗(yàn)證策略函數(shù)
      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設(shè)計(jì)模式--策略模式之輸入驗(yàn)證的全部內(nèi)容,希望大家喜歡。

相關(guān)文章

  • ES6之模版字符串的具體使用

    ES6之模版字符串的具體使用

    這篇文章主要介紹了ES6之模版字符串的具體使用,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-05-05
  • 小程序調(diào)用微信支付的方法

    小程序調(diào)用微信支付的方法

    這篇文章主要為大家詳細(xì)介紹了小程序調(diào)用微信支付的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • Ajax和Comet技術(shù)總結(jié)

    Ajax和Comet技術(shù)總結(jié)

    Ajax是一種技術(shù),一種能夠向服務(wù)器請求額外的數(shù)據(jù)而無需卸載頁面的技術(shù),能夠使網(wǎng)頁具備更優(yōu)的用戶體驗(yàn)。Ajax技術(shù)的核心是XMLHttpRequest對象(XHR)。本文從XHR開始談起,理解Ajax技術(shù)的特點(diǎn),再對跨域以及Comet等技術(shù)進(jìn)行簡要理解和總結(jié)。下面跟著小編一起來看下吧
    2017-02-02
  • js實(shí)現(xiàn)addClass,removeClass,hasClass的函數(shù)代碼

    js實(shí)現(xiàn)addClass,removeClass,hasClass的函數(shù)代碼

    js實(shí)現(xiàn)addClass,removeClass,hasClass的函數(shù)代碼,需要的朋友可以參考下。
    2011-07-07
  • 更優(yōu)雅的微信小程序骨架屏實(shí)現(xiàn)詳解

    更優(yōu)雅的微信小程序骨架屏實(shí)現(xiàn)詳解

    這篇文章主要介紹了更優(yōu)雅的微信小程序骨架屏實(shí)現(xiàn)詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • Javascript Symbol原理及使用方法解析

    Javascript Symbol原理及使用方法解析

    這篇文章主要介紹了Javascript Symbol原理及使用方法解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • js 刷新頁面的代碼小結(jié) 推薦

    js 刷新頁面的代碼小結(jié) 推薦

    這里介紹的是網(wǎng)上比較流行的刷新頁面的代碼,整理的相對比較全了,這些知識都是前后臺結(jié)合過程中,經(jīng)常用的到的。
    2010-04-04
  • 淺談?lì)愃朴?function(){}).call()的js語句

    淺談?lì)愃朴?function(){}).call()的js語句

    這篇文章主要介紹了淺談?lì)愃朴?function(){}).call()的js語句,的相關(guān)資料,需要的朋友可以參考下
    2015-03-03
  • 在微信小程序中使用mqtt服務(wù)的方法

    在微信小程序中使用mqtt服務(wù)的方法

    這篇文章主要介紹了在微信小程序中使用mqtt服務(wù)的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • javascript 最常用的10個(gè)自定義函數(shù)[推薦]

    javascript 最常用的10個(gè)自定義函數(shù)[推薦]

    如果不使用類庫或者沒有自己的類庫,儲備一些常用函數(shù)總是有好處的。
    2009-12-12

最新評論