上面一篇文章,我们已经学会了基本的策略模式的书写,好,现在我们就来用些例子来巩固下
动画现在是页面上一个不可或缺的部分,它会为我们的网页增色不少,下面我们就用策略模式来实现缓动动画
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title></title> <link rel="stylesheet" href=""> <style type="text/css" media="screen"> div{ position:absolute; width:100px; height:100px; background:lime; text-align:center; line-height:100px; } </style> </head> <body> <div id='div'>我要运动</div> <script type="text/javascript" src='js/part3.js'></script> </body> </html>
|
html部分so easy,然后我们来看看js部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| var tween = { linear : function(t,b,c,d){ return c*t/d + b; }, easeIn : function(t,b,c,d){ return c*(t/=d)*t+b }, strongEaseIn : function(t,b,c,d){ return c*(t/=d)*t*t*t*t + b; }, strongEaseOut : function(t,b,c,d){ return c*((t=t/d-1)*t*t*t*t+1)+b; }, sineaseIn : function(t,c,b,d){ return c*(t/=d)*t*t+b }, sineaseOut : function(t,c,b,d){ return c*((t=t/d-1)*t*t+1)+b } };
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) } },100);
}
Animate.prototype.step = function(){ var t = new Date(); console.log(t) console.log(typeof this.startTime) 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 oDiv = document.getElementById('div');
var animate = new Animate(oDiv);
animate.start('left',500,1000,'linear')
|
上面我们先定义了一个缓动算法tween
这个我们也许并不陌生,最初来自flash,它包含四个参数: 动画已消耗的时间
,小球的原始位置
,小球的目标位置( 就是起始点与终点之间的距离)
,整个运动要消耗的时间
然后,我们定义一个动画类Animate
,有一个方法start
,用来设置传进来的参数以及判断运动是否已经结束,step
用来设置每一步要做的事,最后一个update
函数用来实时更新dom的状态
特别要注意的一个问题是
第36
行的this.startTime = +new Date;
这里前面必须不能遗漏这个+
,,他是将一个对象转换为Number类型,从而以便于与第58
行里面的this.startTime + this.duration
这样子,他们相加后的结果还是number
,不然如果是一个对象,那么这个判断永远是false
,dom不会停下,,有的人会说55行不也有个new Date
吗,也要前面加上+
?这里倒是不需要,具体可以自己试试,总结一句话: +new Date就是被对象转换为 Number
懂了上面的例子后,我们最后来看下我们常见的表单验证是如何与策略模式结合的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Eg</title> <link rel="stylesheet" href="https://cdn.rawgit.com/twbs/bootstrap/v4-dev/dist/css/bootstrap.css"> </head> <body class='container'> <form id='registerForm' method='post'> <fieldset class="form-group"> <label for="userName">请输入你的名字</label> <input type="text" class="form-control" name='userName' id="userName" /> </fieldset> <fieldset class="form-group"> <label for="oPassword">请输入密码</label> <input type="password" class="form-control" name='password' id="oPassword" /> </fieldset>
<fieldset class="form-group"> <label for="tel">请输入联系方式</label> <input type="text" class="form-control" name='phone' id="tel" /> </fieldset>
<button type="submit" class="btn btn-primary">提交</button>
</form> <script type="text/javascript" src='js/part5.js'></script> </body> </html>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| var strategies = { isNoEmpty : 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; } } };
var validataFunc = function(){ var validator = new Validator();
validator.add(registerForm.userName,'isNoEmpty','用户名不能为空'); validator.add(registerForm.password,'minLength:6','密码不能少于六位'); validator.add(registerForm.phone,'isMobile','手机号格式不正确');
var errorMsg = validator.start();
return errorMsg; }
var registerForm = document.getElementById('registerForm'); registerForm.onsubmit = function(){ var errorMsg = validataFunc();
if(errorMsg){ alert(errorMsg); return false; }
}
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 ); }) };
Validator.prototype.start = function(){ for( var i=0,validataFunc;validataFunc = this.cache[i++]; ){ var msg = validataFunc(); if( msg ){ return msg } } }
|
具体的你们自己去细细品味吧~~
好了,策略模式,我们就交流到这,如其中有错误的,欢迎指出^_^
最后祝大家新年快乐,万事如意~~
学习自曾探的《Javascript设计模式与开发实战》