如何在浏览器兼容的Javascript中撤消和重做事件?

时间:2016-10-06 11:30:02

标签: javascript jquery

我正在使用T恤自定义设计软件工具,并且必须为可拖动的文本添加重做和撤消事件

http://wordpress.tshirtecommerce.com/design-online/?product_id=17

我尝试过使用撤消管理器插件http://mattjmattj.github.io/simple-undo/

2 个答案:

答案 0 :(得分:1)

我们在这里......

这是一个简单的撤销和放大的例子。重做缓冲区,并使用函数闭包来处理重做..

这当然是一个非常简单的例子,因此希望很容易遵循,但是没有理由不能使用这种技术撤消/重做任何东西。任何东西,你传递给函数闭包都可以捕获,然后进行回放。

var e = {}; //lets store references to the dom elemements
Array.prototype.slice.call(document.querySelectorAll("[id]")).
  forEach(function (el) { e[el.id] = el; });

var stack = [],
    stackPos = 0,
    names = [];

function showNames() {
  e.lbNames.textContent = names.join(', ');
  e.btUndo.disabled =  stackPos <= 0;
  e.btRedo.disabled = stackPos >= stack.length;
  e.lbBuffer.textContent = stack.length;
}

btAdd.onclick = function () {
  if (!ipName.value) return alert("Please enter some text");
  //a function closure to capture the name
  function add(name) {
    return function () {
      e.ipName.value = '';
      e.ipName.focus();
      names.push(name);
      stackPos ++;
      showNames();
    }
  }
  //no need for closure here, as were just going to pop the
  //last one of the names, and shift the undo-pos back
  function undo() {
    stackPos --;
    names.pop(); 
    showNames();
  }
  //now lets add our do & undo proc
  var doadd = add(ipName.value);
  stack.splice(stackPos);
  stack.push({
    do: doadd,
    undo: undo
  });
  //lets now do our inital do
  doadd();
};

btUndo.onclick = function () {
  var p = stack[stackPos - 1];
  p.undo();
};

btRedo.onclick = function () {
  var p = stack[stackPos];
  p.do();
};

showNames();
<form onsubmit="return false">
  name: <input id="ipName">
  <br><br>
  <button type="submit" id="btAdd" >Add</button>
  <button id="btUndo">Undo</button>
  <button id="btRedo">Redo</button>
  Buffer = <span id="lbBuffer"></span>
  <pre id="lbNames"></pre>
</form>

答案 1 :(得分:0)

好吧,有一件事让我对我的原始帖子感到困惑,那就是可重用性。 Undo / Redo也与实现细节紧密相关。

所以我创建了一个可重复使用的课程版本,同时也添加了一个明确的选项。

我认为保留原件很方便,而且这个用于比较。这样人们就可以查看代码并进行比较。

&#13;
&#13;
var e = {}; //lets store references to the dom elemements
Array.prototype.slice.call(document.querySelectorAll("[id]")).
  forEach(function (el) { e[el.id] = el; });


function UndoRedo(update_callback, clear_callback) {
  this.update_callback = update_callback;
  this.clear_callback = clear_callback;
  this.clear();
}

UndoRedo.prototype = {
  
  clear: function () {
    this.stack = [];
    this.stackPos = 0;  
    if (this.clear_callback) this.clear_callback();
    this.update();
  },
  
  update: function () {
    if (this.update_callback) this.update_callback();
  },
  
  canUndo: function () { 
    return this.stackPos > 0; 
  },

  canRedo: function () {
    return this.stackPos < this.stack.length;
  },

  doAction: function (doProc, undoProc) {
    this.stack.splice(this.stackPos);
    this.stack.push({
      do: doProc,
      undo: undoProc
    });
    this.stackPos ++;
    doProc(); 
    this.update();
  },
  
  undo: function () {
    var p = this.stack[this.stackPos - 1];
    this.stackPos --;
    p.undo();
    this.update();
  },
  
  redo: function () {
    var p = this.stack[this.stackPos];
    this.stackPos ++;
    p.do();    
    this.update();
  }
  
};  



var     
    names = [],
    undoRedo = new UndoRedo(
      function update() {
        e.lbNames.textContent = names.join(', ');
        e.btUndo.disabled = !this.canUndo();
        e.btRedo.disabled = !this.canRedo();
        e.lbBuffer.textContent = this.stack.length;
      },
      function cleared() {
        names = [];
      }
    );

btAdd.onclick = function () {
  if (!ipName.value) return alert("Please enter some text");
  
  undoRedo.doAction(
    
    function add(name) {
      return function () {
        e.ipName.value = '';
        e.ipName.focus();
        names.push(name);
      }
    }(ipName.value), 
    
    function undo() {
      names.pop(); 
    }
    
  );  
};

btUndo.onclick = function () {
  undoRedo.undo();
};

btRedo.onclick = function () {
  undoRedo.redo();
};

btClear.onclick = function () {
  undoRedo.clear();
}
&#13;
<form onsubmit="return false">
  name: <input id="ipName">
  <br><br>
  <button type="submit" id="btAdd" >Add</button>
  <button id="btUndo">Undo</button>
  <button id="btRedo">Redo</button>
  Buffer = <span id="lbBuffer"></span>
  <button id="btClear">Clear</button>
  <pre id="lbNames"></pre>
</form>
&#13;
&#13;
&#13;

相关问题