2014-06-16 25 views
2

我正在創建自己的編輯器,並且我正在處理我已經躲過幾個星期的撤消/重做問題。如何使用瀏覽器控件+ z/control + y進行撤銷/重做?

我已經創建了存儲和傳遞的自定義操作的歷史上基本框架,但我似乎無法找到如何與瀏覽器歷史在contentEditable區域互動良好的信息。

看着https://github.com/jzaefferer/undo/blob/master/undo.js,我還是沒有看到這是如何完成的。

我可以撤消/重做我的自定義操作,但我忘記了如何使用瀏覽器的默認歷史記錄。

我必須添加所有的原始功能,如果我重寫默認控制+(Z | Y)

更新:哪裏可以找到關於瀏覽器如何處理這些撤銷/重做操作的更多信息?

+0

您是指他們訪問過的頁面? – TheNorthWes

+0

你不**有**,只要確定你沒有問題就可以創建可用性問題,如果你刪除了部分默認功能。 – blgt

+0

這與頁面歷史無關.. HTML5內容可編輯的歷史..被鍵入的文本,'execCommand'等。@blgt是否沒有辦法讓2個簡單的共存?如果我能找到一個關於它如何工作的資源,我會更好地瞭解什麼可以做和不可以做什麼。 –

回答

1

查看contenteditable demo的來源,瞭解更多關於他如何將庫附加到div的信息。

$(function() { 
    var stack = new Undo.Stack(), 
     EditCommand = Undo.Command.extend({ 
      constructor: function(textarea, oldValue, newValue) { 
       this.textarea = textarea; 
       this.oldValue = oldValue; 
       this.newValue = newValue; 
      }, 
      execute: function() { 
      }, 
      undo: function() { 
       this.textarea.html(this.oldValue); 
      }, 

      redo: function() { 
       this.textarea.html(this.newValue); 
      } 
     }); 
    stack.changed = function() { 
     stackUI(); 
    }; 

    var undo = $(".undo"), 
     redo = $(".redo"), 
     dirty = $(".dirty"); 
    function stackUI() { 
     undo.attr("disabled", !stack.canUndo()); 
     redo.attr("disabled", !stack.canRedo()); 
     dirty.toggle(stack.dirty()); 
    } 
    stackUI(); 

    $(document.body).delegate(".undo, .redo, .save", "click", function() { 
     var what = $(this).attr("class"); 
     stack[what](); 
     return false; 
    }); 

    var text = $("#text"), 
     startValue = text.html(), 
     timer; 
    $("#text").bind("keyup", function() { 
     // a way too simple algorithm in place of single-character undo 
     clearTimeout(timer); 
     timer = setTimeout(function() { 
      var newValue = text.html(); 
      // ignore meta key presses 
      if (newValue != startValue) { 
       // this could try and make a diff instead of storing snapshots 
       stack.execute(new EditCommand(text, startValue, newValue)); 
       startValue = newValue; 
      } 
     }, 250); 
    }); 

    $(".bold").click(function() { 
     document.execCommand("bold", false); 
     var newValue = text.html(); 
     stack.execute(new EditCommand(text, startValue, newValue)); 
     startValue = newValue; 
    }); 

      // This is where he attaches the observer for undo/redo. 
      // For more information: https://stackoverflow.com/questions/16006583/capturing-ctrlz-key-combination-in-javascript 
    $(document).keydown(function(event) { 
     if (!event.metaKey || event.keyCode != 90) { 
      return; 
     } 
     event.preventDefault(); 
     if (event.shiftKey) { 
      stack.canRedo() && stack.redo() 
     } else { 
      stack.canUndo() && stack.undo(); 
     } 
    }); 
}); 

Capturing ctrl+z key combination in javascript

0

我不相信有無論如何直接訪問撤消緩衝區的內容,但你可以引發撤消或使用document.execCommand重做。簡單的例子:

<html> 
<head> 
<style> 
    #box { 
    width: 200px; 
    height: 100px; 
    background-color: grey; 
    } 
</style> 
</head> 
<body> 
    <div id="box" contenteditable="true"></div> 
    <button id="undo">Undo</button> 
    <button id="redo">Redo</button> 
<script> 
    var box = document.getElementById('box'); 
    var undo = document.getElementById('undo'); 
    var redo = document.getElementById('redo'); 

    undo.addEventListener('click', function (ev) { 
    document.execCommand('undo', false, null); 
    }); 

    redo.addEventListener('click', function (ev) { 
    document.execCommand('redo', false, null); 
    }); 
</script> 
</body> 
</html> 

檢查它是作爲一個jsfiddle

+0

這並不能真正幫助我的情況。我知道我可以爲'execCommand'函數執行此操作,但輸入的文本等內容遠遠超出了此答案的範圍。默認的撤消/重做比粗體/不重複等要多得多。我只是需要它來做更多*,並且與我的自定義操作共存。它看起來像我必須「破解」默認功能並完全覆蓋它。 –

+0

我認爲你應該澄清一下你的問題。你的問題似乎是關於如何訪問默認的撤消/重做功能,即使覆蓋典型的(ctrl-c/z)快捷方式。如果你解釋了你想完成的事情,這將有所幫助。你需要什麼_even more_功能?我認爲這個問題有一個[XY問題](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)。 – Ben

1

使用此功能,但它的工作方式與<div contentEditable="true">框一樣。在textarea中,它一次性撤銷並重寫所有文本,而不是像div一樣逐字地重寫。

<script language="JavaScript"> 
function Undo() { document.execCommand("undo", false, null); } 
function Redo() { document.execCommand("redo", false, null); } 
</script> 

<div contentEditable="true" style="background-color:rgba(0,0,0,0.8); resize:none; width: 499px; height: 230px; border: 1px solid red;"></div> 
<input type="button" onmouseup="Undo()" value="Undo" /> 
<input type="button" onmouseup="Redo()" value="Redo" />