• 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              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 </html>
  • 相关阅读:
    unzip解压3G或者4G以上文件失败的解决方法
    zencart批量删除无图片产品
    zencart后台管理中选项名称和选项内容和属性控制页面出错解决办法 WARNING: An Error occurred, please refresh the page and try again
    在线随机密码生成工具
    zencart更改css按钮的宽度css buttons
    IE8"HTML Parsing Error:Unable to modify the parent container element before the child element is closed"错误
    css改变背景透明度
    phpMyAdmin出现Fatal error: Maximum execution time of 300 seconds
    da面板修改SSH端口号
    原生js三级联动
  • 原文地址:https://www.cnblogs.com/cangqinglang/p/9795646.html
Copyright © 2020-2023  润新知