1. 程式人生 > >javascript設計模式二: 策略模式

javascript設計模式二: 策略模式

31 32//為元素同時設定多個屬性方法 33var setAttributes = function(el, attrs){ 34    for(var key in attrs){ 35        el.setAttribute(key, attrs[key]) 36    } 37} 38 39//策略類 40var strategiesObj = { 41    isNonEmptyfunction(name, value, errorMsg){ 42        if(value === ''){ 43            var errObj = {errName: name, errValue
: value, errMsg: errorMsg} 44            return errObj 45        } 46    }, 47    minLengthfunction(name, value, length, errorMsg){ 48        if(value.length < length){ 49            var errObj = {errName: name, errValue: value, errLength: length, errMsg: errorMsg} 50            return errObj 51
        } 52    }, 53    isMobilefunction(name, value, errorMsg){ 54        if(!/^1[3|4|5|7|8][0-9]{9}$/.test(value)){ 55            var errObj = {errName: name, errValue: value, errMsg: errorMsg} 56            return errObj 57        } 58    } 59} 60 61//Context類 62var Validator = function(){ 63    this
.cache = [];     //儲存校驗規則 64    this.errArr = []; 65} 66 67Validator.prototype.add = function(name, dom, rules){ 68    var self = this; 69    for(var i=0, rule; rule=rules[i++];){ 70        (function(rule){ 71            var strategyAry = rule.strategy.split(':');   //把strategy和rule分隔開 72            self.cache.push(function(){     //把校驗的步驟用空函式包裹起來,並且放入cache中, 73                var strategy = strategyAry.shift(strategyAry);   //使用者選擇的strategy   shift()方法是刪除陣列第一個元素,並返回第一個元素的值 74                strategyAry.unshift(name) 75                strategyAry.splice(10, dom.value)   //把input的value新增進引數列表      unshift()方法是向陣列的頭部新增元素,並返回新陣列的長度 76                strategyAry.push(rule.errorMsg)      //把errorMsg新增進引數列表 77                return strategiesObj[strategy].apply(null, strategyAry) 78            }) 79        })(rule) 80    } 81} 82 83Validator.prototype.start = function(){ 84    var msgArr = []; 85    var msgObj = {}; 86    for(var i=0this.cache[i]; i++){    //此處的this.cache[i]函式是在this.cache陣列中儲存的校驗規則函式 87        var resultArgs = this.cache[i]();   //開始校驗,並取得校驗後返回資訊 88        if(resultArgs){    //如果有確切的返回值,說明校驗沒有通過 89            msgArr.push({    //將策略類具體方法的返回值組合成陣列物件,包含錯誤表單的索引、name、value、錯誤資訊及其他自定義配置資訊如長度 90                errIndex:i,  91                errName: resultArgs.errName,  92                errValue: resultArgs.errValue,  93                errMsg: resultArgs.errMsg,  94                errLength: resultArgs.errLength?resultArgs.errLength:'' 95            }) 96        } 97    } 98    this.errArr = msgArr; 99    return msgArr100}101102Validator.prototype.errShow = (function(){103    var singleErr = null;104105    return function(){106        console.log(singleErr);107        if(!singleErr){108            for(var i=0, l=this.errArr.length; i<l; i++){109                var label = document.createElement('label')110                label.innerHTML = this.errArr[i].errMsg111                setAttributes(label, {112                    'for'this.errArr[i].errName,113                    'id'this.errArr[i].errName + '-error',114                    'class''error'115                })116                //原生js插入兄弟節點是方法是獲取父節點然後通過appendChild或者insertBefore方法插入117                document.getElementsByName(this.errArr[i].errName)[0].parentNode.append(label)118            }119        }120        return singleErr = label;121    }122})()123124//例項化Validator類125var ValidatorFunc = function(){126    var validator = new Validator();        //建立一個validator物件127128    //新增一些校驗規則129    validator.add('username', registerForm.username, [{strategy'isNonEmpty'errorMsg'使用者名稱不能為空'}])130    validator.add('password', registerForm.password, [{strategy'minLength:6'errorMsg'密碼長度不能少於6位'}])131    validator.add('phoneNumber', registerForm.phoneNumber, [{strategy'isMobile'errorMsg'手機號碼格式不正確'}, {strategy'minLength:11'errorMsg'手機號長度不能少於11位'}])132133    var errorMsgArr = validator.start();   //獲得校驗結果134    validator.errShow()135    return errorMsgArr;    //返回校驗結果136}137138//實際表單校驗呼叫139var registerForm = document.getElementById('registerForm')140registerForm.onsubmit = function(){141    var errorMsgArr = ValidatorFunc(); //如果errorMsg有確切的返回值,說明未通過校驗142    if(errorMsgArr){143        console.log(errorMsgArr);144        return false    //阻止表單提交145    }146}147148