0
点赞
收藏
分享

微信扫一扫

JavaScript设计模式-----命令模式的简单应用

命令模式是最简单和优雅的模式之一,命令模式中的命令(command)是指一个执行某些特定事情的指令。

应用场景:有时候需要向某些对象发送请求,但是并不知道请求的接受者是谁,也不知道被请求的操作是什么,此时希望用一种

松解耦的方式来设计软件,使得请求发送者和请求接受者能够消除彼此之间的耦合关系。

 

一个简单JavaScript例子:

1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>命令模式</title>
6 <style>
7 body{
8 padding: 0;
9 margin: 0;
10 }
11 .ball{
12 position: absolute;
13 background: #000;
14 width: 50px;
15 height: 50px;
16 top: 200px;
17 }
18 </style>
19 </head>
20 <body>
21 <div id="ball" class="ball"></div>
22 输入小球移动后的位置:<input type="text" id="pos">
23 <button id="moveBtn">开始移动</button>
24 <button id="cancelBtn">cancel</button>
25 <script>
26
27 // 营运策略模式封装一系列缓动算法
28 // t:已消耗的时间 b:小球的原始位置 c:小球的目标位置 d:动画持续的总时间
29 // 返回当前位置
30 var tween = {
31 linear: function(t, b, c, d) {
32 return c*t/d + b;
33 },
34 easeIn: function(t, b, c, d) {
35 return c * (t /= d) * t + b;
36 },
37 strongEaseIn: function(t, b, c, d) {
38 return c * (t /= d) * t * t * t + b;
39 },
40 strongEaseOut: function(t, b, c, d) {
41 return c * (( t = t / d - 1 ) * t * t * t * t + 1) + b;
42 },
43 sineaseIn: function(t, b, c, d) {
44 return c * (t /= d) * t * t + b;
45 },
46 sineaseOut: function(t, b, c, d) {
47 return c * (( t = t / d - 1) * t * t + 1) + b;
48 }
49 };
50
51 // 定义动画类
52 var Animate = function(dom) {
53 this.dom = dom;
54 this.startTime = 0;
55 this.startPos = 0;
56 this.endPos = 0;
57 this.propertyName = null;
58 this.easing = null;
59 this.duration = null;
60 }
61
62 // 动画启动
63 Animate.prototype.start = function(propertyName, endPos, duration, easing) {
64 this.propertyName = propertyName;
65 this.startTime = +new Date();
66 this.startPos = this.dom.getBoundingClientRect()[propertyName];
67 this.endPos = endPos;
68 this.duration = duration;
69 this.easing = tween[easing];
70
71 var self = this;
72 var timeId = setInterval(function() {
73 if (self.step() === false) {
74 clearInterval(timeId);
75 }
76 }, 1000/60)
77 }
78
79 Animate.prototype.step = function() {
80 var t = +new Date();
81 if (t > this.startTime + this.duration) {
82 this.update(this.endPos);
83 return false;
84 }
85 var pos = this.easing(t - this.startTime,
86 this.startPos, this.endPos - this.startPos, this.duration);
87 this.update(pos);
88 }
89
90 Animate.prototype.update = function( pos ) {
91 this.dom.style[ this.propertyName ] = pos + 'px';
92 }
93
94
95 var ball = document.getElementById('ball');
96 var pos = document.getElementById('pos');
97 var moveBtn = document.getElementById('moveBtn');
98 var cancelBtn = document.getElementById('cancelBtn');
99
100 // 使用命令模式实现事件和dom的解耦
101 var MoveCommand = function(receiver, pos) {
102 this.receiver = receiver;
103 this.pos = pos;
104 this.oldPos = null;
105 }
106
107 MoveCommand.prototype.excute = function() {
108 this.receiver.start('left', this.pos, 1000, 'strongEaseOut');
109 this.oldPos = this.receiver.dom.getBoundingClientRect()[this.receiver.propertyName];
110 }
111
112 MoveCommand.prototype.undo = function() {
113 this.receiver.start('left', this.oldPos, 1000, 'strongEaseOut');
114 }
115
116 var moveCommand;
117
118 moveBtn.onclick = function() {
119 var animate = new Animate( ball );
120 moveCommand = new MoveCommand(animate, pos.value);
121 moveCommand.excute();
122 }
123
124 cancelBtn.onclick = function() {
125 console.log(moveCommand);
126 moveCommand.undo();
127 }
128 </script>
129 </body>
130

 



举报

相关推荐

0 条评论