【代碼筆記】js策略模式

策略模式算法

特色  由一個上下文對象負責選擇策略,將策略的實現委託給策略類,節省if-else判斷分支app

實現思路 定義算法(即策略)族,將算法的使用與實現隔離dom

/* 策略模式 模板    
*/
var strategies = function  () {
    "s1" : function  ( arg ) {
        // body...
    },
    "s2" :function  ( arg ) {
        // body...
    }
    //,"s3"...
}
var context = function  ( str, arg ) {
    return strategies[ str ]( arg );
}

實例 緩動動畫,表單驗證動畫

//策略模式 示例:緩動動畫
//緩動效果策略族
var tween = {
    linear: function  ( t, b, c, d ) {
        return c*t /d +b;
    },
    easyin: function  ( t, b, c, d ) {
        return c* ( t /= d ) *t +b; 
    }
}
//曲線策略族
var path = {
    //beze:
}
var Animate = function  ( dom ) {
    this.dom = dom;
    this.startTime = 0;
    this.startPos = 0;
    this.endPos = 0;
    this.propertyName = null;
    this.easing = null;
    this.duration = null;
};
Animate.prototype.start = function  ( propertyName, endPos, duration, easing ) {
    this.startTime = +new Date;
    this.startPos = this.dom.getBoundingClientRect()[ propertyName ];
    this.propertyName = propertyName;
    this.endPos = endPos;
    this.duration = duration;
    this.easing = tween[ easing ];
    var self = this;
    var timeId = setInterval(function  () {
        if ( self.step() == false ){
            clearInterval(timeId);
        }
    },19);
};
Animate.prototype.step = function  ( propertyName, endPos, duration, easing ) {
    var t = +new Date;
    if( t >= this.startTime + this.duration ){
        this.update( this.endPos );
        return false;
    }
    var pos = this.easing( t-this.startTime, this.startPos, this.endPos - this.startPos, this.duration );
    this.update( pos );
};
Animate.prototype.update = function  ( pos ) {
    this.dom.style[ this.propertyName ] = pos + 'px';
};

var div = document.getElementById( 'xxx' );
var animate = new Animate( div );
animate.start('left', 500, 1000, 'easyin');
//策略模式 示例:表單校驗
/* @strategies 驗證規則族*/
var strategies = {
    isNotEmpty : function  ( value, errMsg ) {
        if ( value === '' ){
            return errMsg;
        }
    },
    minLength: function  ( value, length, errMsg ) {
        if( value.length < length ){
            return errMsg;
        }
    },
    maxLength: function  ( value, length, errMsg ) {
        if( value.length > length ){
            return errMsg;
        }
    },
    isMobile: function  ( value, errMsg ) {
        if( ! /(^1[3|5|8][0-9]{9}$)/ .test( value ) ){
            return errMsg;
        }
    }
};

var Validator = function  () {
    this.cache = [];
};
Validator.prototype.add = function  ( dom, rules ) {
    var self = this;
    for ( var i =0, rule; rule = rules[ i++ ]; ){
        (function  ( rule ) {
            var ary = rule.strategy.split( ':' );
            var errorMsg = rule.errorMsg;
            self.cache.push(function  () {
                var strategy = ary.shift();
                ary.unshift( dom.value );
                ary.push( errorMsg );
                return strategies[ strategy ].apply( dom, ary );
            });
        })( rule );
    }
};
Validator.prototype.start = function  () {
    for( var i = 0, validataFunc; validataFunc = this.cache[ i++ ]; ){
        var msg = validataFunc();
        if( msg ){
            return msg;
        }
    }
};

//表單校驗使用場景
/* @validataFunc 驗證規則配置*/
var xxxForm = document.getElementById( 'xxxForm' );

var validataFunc = function  () {
    var validator = new Validator();
    //註冊validator的驗證規則
    validator.add( xxxForm.userName, [
        {
            strategy: 'isNotEmpty',
            errorMsg: '用戶名不能爲空'
        },
        {
            strategy: 'minLength:6',
            errorMsg: '用戶名長度不能小於6位'
        },
        {
            strategy: 'maxLength:20',
            errorMsg: '用戶名長度不能小於20位'
        }
    ] );
    
    validator.add( xxxForm.password, [
        {
            strategy: 'minLength:6',
            errorMsg: '密碼長度不能少於6位'
        }
    ]);
    validator.add( xxxForm.phoneNumber, [
        {
            strategy: 'isMobile',
            errorMsg: '手機號碼格式不正確'
        }
    ]);

    var errMsg = validator.start();
    return errMsg;
};
function check (  ) {
    
}
xxxForm.onsubmit= function  () {
     
    var errorMsg = validataFunc();
    if( errorMsg ){ //errorMsg不爲空,表示驗證不經過,阻止提交表單
        //阻止提交表單的代碼
        alert( errorMsg );
        return false;
    }
};
相關文章
相關標籤/搜索