命令模式

      var button1 = document.getElementById("button1");
      var button2 = document.getElementById("button2");
      var button3 = document.getElementById("button3");
      var setCommand = function (button, command) {
        button.onclick = function () {
          command.execute();
        };
      };
      var MenuBar = {
        refresh: function () {
          console.log("刷新菜单目录");
        },
      };
      var SubMenu = {
        add: function () {
          console.log("增加子菜单");
        },
        del: function () {
          console.log("删除子菜单");
        },
      };
      class RefreshMenuBarCommand {
        constructor(receiver) {
          this.receiver = receiver;
        }
        execute() {
          this.receiver.refresh();
        }
      }
      class DelSubMenuCommand {
        constructor(receiver) {
          this.receiver = receiver;
        }
        execute() {
          console.log("删除子菜单");
        }
      }
      class AddSubMenuCommand {
        constructor(receiver) {
          this.receiver = receiver;
        }
        execute() {
          this.receiver.add();
        }
      }
      var refreshMenuBarCommand = new RefreshMenuBarCommand(MenuBar);
      var addSubMenuCommand = new AddSubMenuCommand(SubMenu);
      var delSubMenuCommand = new DelSubMenuCommand(SubMenu);
      setCommand(button1, refreshMenuBarCommand);
      setCommand(button2, addSubMenuCommand);
      setCommand(button3, delSubMenuCommand);

 简化:

var bindClick = function( button, func ){
button.onclick = func;
};
var MenuBar = {
refresh: function(){
console.log( '刷新菜单界面' );
}
};
var SubMenu = {
add: function(){
console.log( '增加子菜单' );
},
del: function(){
console.log( '删除子菜单' );
}
};
bindClick( button1, MenuBar.refresh );
bindClick( button2, SubMenu.add );
bindClick( button3, SubMenu.del );

 

 

 

 

动画的

 <body>
    <div
      id="ball"
      style="position: absolute; background: #000; width: 50px; height: 50px;"
    ></div>
    输入小球移动后的位置:<input id="pos" />
    <button id="moveBtn">开始移动</button>
    <button id="cancelBtn">cancel</cancel> 
    <script>
      var ball = document.getElementById("ball");
      var pos = document.getElementById("pos");
      var moveBtn = document.getElementById("moveBtn");
      var cancelBtn = document.getElementById( 'cancelBtn' );
      //   moveBtn.onclick = function () {
      //     var animate = new Animate(ball);
      //     animate.start("left", pos.value, 1000, "strongEaseOut");
      //   };
      var MoveCommand = function( receiver, pos ){
        this.receiver = receiver;
        this.pos = pos;
        this.oldPos = null;
    }
      MoveCommand.prototype.execute = function () {
        this.receiver.start("left", this.pos, 1000, "strongEaseOut");
      };
      MoveCommand.prototype.undo = function () {
        this.receiver.start( 'left', this.oldPos, 1000, 'strongEaseOut' );
      };
 
      var moveCommand;
 
      moveBtn.onclick = function () {
        var animate = new Animate(ball);
        moveCommand = new MoveCommand(animate, pos.value);
        moveCommand.execute();
      };
      cancelBtn.onclick = function () {
          if(moveCommand){
            moveCommand.undo(); 

          }
      };
      //
      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, b, c, d) {
          return c * (t /= d) * t * t + b;
        },
        sineaseOut: function (t, b, c, d) {
          return c * ((t = t / d - 1) * t * t + 1) + b;
        },
      };
      var Animate = function (dom) {
        this.dom = dom; // 进行运动的 dom 节点
        this.startTime = 0; // 动画开始时间
        this.startPos = 0; // 动画开始时,dom 节点的位置,即 dom 的初始位置
        this.endPos = 0; // 动画结束时,dom 节点的位置,即 dom 的目标位置
        this.propertyName = null; // dom 节点需要被改变的 css 属性名
        this.easing = null; // 缓动算法
        this.duration = null; // 动画持续时间
      };
      Animate.prototype.start = function (
        propertyName,
        endPos,
        duration,
        easing
      ) {
        this.startTime = +new Date(); // 动画启动时间
        this.startPos = this.dom.getBoundingClientRect()[propertyName]; // dom 节点初始位置
        this.propertyName = propertyName; // dom 节点需要被改变的 CSS 属性名
        this.endPos = endPos; // dom 节点目标位置
        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 () {
        var t = +new Date(); // 取得当前时间
        if (t >= this.startTime + this.duration) {
          // (1)
          this.update(this.endPos); // 更新小球的 CSS 属性值
          return false;
        }
        var pos = this.easing(
          t - this.startTime,
          this.startPos,
          this.endPos - this.startPos,
          this.duration
        );
        // pos 为小球当前位置
        this.update(pos); // 更新小球的 CSS 属性值
      };
      Animate.prototype.update = function (pos) {
        this.dom.style[this.propertyName] = pos + "px";
      };

 

 

 

 

 

 

 

另外一个案例

 <button id="replay">播放录像</button>
    <script>
      var Ryu = {
        attack: function () {
          console.log("攻击");
        },
        defense: function () {
          console.log("防御");
        },
        jump: function () {
          console.log("跳跃");
        },
        crouch: function () {
          console.log("蹲下");
        },
      };
      var makeCommand = function (receiver, state) {
        // 创建命令
        return function () {
          receiver[state]();
        };
      };
      var commands = {
        "119": "jump", // W
        "115": "crouch", // S
        "97": "defense", // A
        "100": "attack", // D
      };
      var commandStack = []; // 保存命令的堆栈
      document.onkeypress = function (ev) {
        var keyCode = ev.keyCode,
          command = makeCommand(Ryu, commands[keyCode]);
        if (command) {
          command(); // 执行命令
          commandStack.push(command); // 将刚刚执行过的命令保存进堆栈
        }
      };
      document.getElementById("replay").onclick = function () {
        // 点击播放录像
        var command;
        while ((command = commandStack.shift())) {
          // 从堆栈里依次取出命令并执行
          command();
        }
      };

 

posted @ 2020-06-19 09:44  TTtttt5  阅读(126)  评论(0编辑  收藏  举报