<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>javascript高级语法21-命令模式</title>
</head>
<body>
<input type="text" id="flow" />
<input type="button" id="" value="添加新流程" onclick="API.addFlow()" /><br>
<input type="button" value="回退" onclick="API.re()" />
<input type="button" value="重做" onclick="API.again()" />
<div id="div01"></div> <script id="uuid.js">
//生成uuid的轮子
/*
uuid.js - Version 0.2
JavaScript Class to create a UUID like identifier
*/ // On creation of a UUID object, set it's initial value
function UUID(){
this.id = this.createUUID();
}
// When asked what this Object is, lie and return it's value
UUID.prototype.valueOf = function(){ return this.id; }
UUID.prototype.toString = function(){ return this.id; }
UUID.prototype.createUUID = function(){
var dg = new Date(1582, 10, 15, 0, 0, 0, 0);
var dc = new Date();
var t = dc.getTime() - dg.getTime();
var h = '-';
var tl = UUID.getIntegerBits(t,0,31);
var tm = UUID.getIntegerBits(t,32,47);
var thv = UUID.getIntegerBits(t,48,59) + '1'; // version 1, security version is 2
var csar = UUID.getIntegerBits(UUID.rand(4095),0,7);
var csl = UUID.getIntegerBits(UUID.rand(4095),0,7);
var n = UUID.getIntegerBits(UUID.rand(8191),0,7) +
UUID.getIntegerBits(UUID.rand(8191),8,15) +
UUID.getIntegerBits(UUID.rand(8191),0,7) +
UUID.getIntegerBits(UUID.rand(8191),8,15) +
UUID.getIntegerBits(UUID.rand(8191),0,15); // this last number is two octets long
return tl + h + tm + h + thv + h + csar + csl + h + n;
} UUID.getIntegerBits = function(val,start,end){
var base16 = UUID.returnBase(val,16);
var quadArray = new Array();
var quadString = '';
var i = 0;
for(i=0;i<base16.length;i++){
quadArray.push(base16.substring(i,i+1));
}
for(i=Math.floor(start/4);i<=Math.floor(end/4);i++){
if(!quadArray[i] || quadArray[i] == '') quadString += '0';
else quadString += quadArray[i];
}
return quadString;
} UUID.returnBase = function(number, base){ var convert = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
if (number < base) var output = convert[number];
else {
var MSD = '' + Math.floor(number / base);
var LSD = number - MSD*base;
if (MSD >= base) var output = this.returnBase(MSD,base) + convert[LSD];
else var output = convert[MSD] + convert[LSD];
}
return output;
}
UUID.rand = function(max){
return Math.floor(Math.random() * max);
} </script>
<script id="keymaster.js">
//获取键盘事件的轮子
(function(a) {
function h(a, b) {
var c = a.length;
while (c--) if (a[c] === b) return c;
return -1
}
function i(a) {
var b, g, i, j, k;
b = a.keyCode;
if (b == 93 || b == 224) b = 91;
if (b in d) {
d[b] = !0;
for (i in f) f[i] == b && (l[i] = !0);
return
}
if (!l.filter.call(this, a)) return;
if (!(b in c)) return;
for (j = 0; j < c[b].length; j++) {
g = c[b][j];
if (g.scope == e || g.scope == "all") {
k = g.mods.length > 0;
for (i in d) if (!d[i] && h(g.mods, +i) > -1 || d[i] && h(g.mods, +i) == -1) k = !1;
(g.mods.length == 0 && !d[16] && !d[18] && !d[17] && !d[91] || k) && g.method(a, g) === !1 && (a.preventDefault ? a.preventDefault() : a.returnValue = !1, a.stopPropagation && a.stopPropagation(), a.cancelBubble && (a.cancelBubble = !0))
}
}
}
function j(a) {
var b = a.keyCode,
c;
if (b == 93 || b == 224) b = 91;
if (b in d) {
d[b] = !1;
for (c in f) f[c] == b && (l[c] = !1)
}
}
function k() {
for (b in d) d[b] = !1;
for (b in f) l[b] = !1
}
function l(a, b, d) {
var e, h, i, j;
d === undefined && (d = b, b = "all"), a = a.replace(/\s/g, ""), e = a.split(","), e[e.length - 1] == "" && (e[e.length - 2] += ",");
for (i = 0; i < e.length; i++) {
h = [], a = e[i].split("+");
if (a.length > 1) {
h = a.slice(0, a.length - 1);
for (j = 0; j < h.length; j++) h[j] = f[h[j]];
a = [a[a.length - 1]]
}
a = a[0], a = g[a] || a.toUpperCase().charCodeAt(0), a in c || (c[a] = []), c[a].push({
shortcut: e[i],
scope: b,
method: d,
key: e[i],
mods: h
})
}
}
function m(a) {
var b = (a.target || a.srcElement).tagName;
return b != "INPUT" && b != "SELECT" && b != "TEXTAREA"
}
function n(a) {
e = a || "all"
}
function o() {
return e || "all"
}
function p(a) {
var b, d, e;
for (b in c) {
d = c[b];
for (e = 0; e < d.length;) d[e].scope === a ? d.splice(e, 1) : e++
}
}
function q(a, b, c) {
a.addEventListener ? a.addEventListener(b, c, !1) : a.attachEvent && a.attachEvent("on" + b, function() {
c(window.event)
})
}
var b, c = {},
d = {
16: !1,
18: !1,
17: !1,
91: !1
},
e = "all",
f = {
"⇧": 16,
shift: 16,
"⌥": 18,
alt: 18,
option: 18,
"⌃": 17,
ctrl: 17,
control: 17,
"⌘": 91,
command: 91
},
g = {
backspace: 8,
tab: 9,
clear: 12,
enter: 13,
"return": 13,
esc: 27,
escape: 27,
space: 32,
left: 37,
up: 38,
right: 39,
down: 40,
del: 46,
"delete": 46,
home: 36,
end: 35,
pageup: 33,
pagedown: 34,
",": 188,
".": 190,
"/": 191,
"`": 192,
"-": 189,
"=": 187,
";": 186,
"'": 222,
"[": 219,
"]": 221,
"\\": 220
};
for (b = 1; b < 20; b++) f["f" + b] = 111 + b;
for (b in f) l[b] = !1;
q(document, "keydown", i), q(document, "keyup", j), q(window, "focus", k), a.key = l, a.key.setScope = n, a.key.getScope = o, a.key.deleteScope = p, a.key.filter = m, typeof module != "undefined" && (module.exports = key)
})(this);
</script>
<script>
/*命令模式:
* 用于消除调用者和接收者之间的耦合的模式
* 并且可以对(调用这个过程进行留痕操作)
* 不能乱用这个模式,它会使简单调用的写法变得非常复杂和难以理解
* 当你的业务出现了回退操作,重做操作等需求的时候考虑用这个模式
*/
/*需求:
有一个添加流程的按钮,单机的时候添加一个新的文本当做流程的描述
有返回 重做两个按钮,完成相应任务。
*/
function manager(){
this.addFlow = function(id,text){
//1.得到目标节点
var div = document.getElementById("div01");
var newFlow = document.createElement("div");
newFlow.setAttribute("id",id);
newFlow.innerHTML = text;
div.appendChild(newFlow);
}
}
//为对象建立命令访问库
manager.prototype.excute = (function(){
//命令对象
return function(command){
return this[command.method](command.id,command.value)
}
})()
//初始化主类
var ma = new manager();
//用于存储调用对象命令的集合。
var commands = new Array();
//集合的游标
var index = commands.length;
//客户端 var API = function(){
this.addFlow = function(){
//把调用封装起来
var command = {
method:"addFlow",
id:new UUID().createUUID(),
value:document.getElementById("flow").value,
}
//把调用对象保存起来,用于回退和重做
commands.push(command);
//重新定位游标
index = commands.length;
//调用
ma.excute(command); }
//返回
this.re = function(){
if(index-1<0){
alert("已经到最后一步了!")
}else{
all = document.getElementById("div01").childNodes;
document.getElementById("div01").removeChild(all[all.length-1]);
index = index - 1;
}
}
//重做
this.again = function(){
if(index>=commands.length){
alert("已经到了最新一步了,不能继续重做了!")
}else{
var command = commands[index];
ma.excute(command);
index = index + 1;
}
}
}
//实例化api
var API = new API(); //添加支持键盘事件
key("ctrl+z",function(){
API.re();
})
key("ctrl+shift+z",function(){
API.again();
})
</script>
</body>
</html>

最新文章

  1. MySQL复制环境(主从/主主)部署总结性梳理
  2. 《Entity Framework 6 Recipes》中文翻译系列 (15) -----第三章 查询之与列表值比较和过滤关联实体
  3. MyBatis入门学习教程-Mybatis3.x与Spring4.x整合
  4. JS实现表格排序
  5. CodeForces - 416A (判断大于小于等于 模拟题)
  6. 第一篇 Replication:复制简介
  7. appium获取android app的包名和主Activity
  8. 【Nginx系列】Nginx编译与安装
  9. 51nod 1686 第k大区间
  10. PHP将图片转base64编码以及base64图片转换为图片并保存代码
  11. HDU 2459 Maximum repetition substring
  12. OGG-01668
  13. Loadrunner&#160;脚本录制-通过代理录制脚本
  14. fasterxml.jackson 将对象转换为json报错处理
  15. C:基础知识
  16. Fiddler抓包域名过滤(转载)
  17. EasyTouch基本用法
  18. c# 获取应用程序exe文件路径及退出应用程序的几种方法
  19. 掀开图片显示介绍的css效果
  20. 【转载】make: Nothing to be done for `all&#39;. 解决方法

热门文章

  1. FTP服务器的搭建与安全配置
  2. java和json互转
  3. [PHP]socket的连接超时 与 读取/写入超时
  4. TSQL--如何突破PRINT的8000大限
  5. 对virtual虚方法的理解
  6. asp.net 添加错误日志
  7. Linq与数据库的连接显示查询(一)
  8. SQL 增加列
  9. CodeChef March Challenge 2019题解
  10. Cannot sending data from mongodb into elasticsearch using logstash