命令模式
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();
}
};


浙公网安备 33010602011771号