如何"撤消"将文本编程插入文本区域?

slu*_*her 17 javascript jquery textarea undo

我有一个textarea和一个按钮.单击该按钮可将文本插入文本区域.

有没有办法允许用户按Ctrl/Cmd + z撤消文本的插入并将textarea恢复到以前的状态?

Kal*_*mah 9

我认为最简单的方法是利用浏览器的撤销堆栈而不是捕获事件.

为此,您需要为不同的浏览器使用不同的代码.幸运的是,在所有主流浏览器中,只有Firefox有不同的方法.

// http://stackoverflow.com/a/9851769/529024
// Opera 8.0+
var isOpera = (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;

// Firefox 1.0+
var isFirefox = typeof InstallTrigger !== 'undefined';

// Safari 3.0+ "[object HTMLElementConstructor]" 
var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0 || (function(p) {
  return p.toString() === "[object SafariRemoteNotification]";
})(!window['safari'] || safari.pushNotification);

// Internet Explorer 6-11
var isIE = /*@cc_on!@*/ false || !!document.documentMode;

// Edge 20+
var isEdge = !isIE && !!window.StyleMedia;

// Chrome 1+
var isChrome = !!window.chrome && !!window.chrome.webstore;



var position = 0;

// text to anser
var text = 'Inserted Text';

// Just for fun :)
if (isFirefox)
  text = "  __ Firefox __ ";
else if (isIE)
  text = "  __ IE __ ";
else if (isEdge)
  text = "  __ Edge __ ";
else if (isSafari)
  text = "  __ Safari __ ";
else if (isOpera)
  text = "  __ Opera __ ";
else if (isChrome)
  text = "  __ Chrome __ ";

/* Adding text on click based on browser */
jQuery(".addText").on("click", function() {
  if (isFirefox) {
    // Firefox
    var val = jQuery(".textArea").val();

    var firstText = val.substring(0, position);
    var secondText = val.substring(position);

    jQuery(".textArea").val(firstText + text + secondText);
  } else {

    jQuery(".textArea").focus();
    var val = jQuery(".textArea").val();

    jQuery(".textArea")[0].selectionStart = position;
    jQuery(".textArea")[0].selectionEnd = position;

    document.execCommand('insertText', false, text);
  }
});

jQuery(".textArea").on("focusout", function(e) {
  position = jQuery(this)[0].selectionStart;
});
Run Code Online (Sandbox Code Playgroud)
textarea {
  padding: 10px;
  font-family: Calibri;
  font-size: 18px;
  line-height: 1.1;
  resize: none;
}
.addText {
  padding: 5px 15px;
  transition: all 0.5s;
  border: 1px solid black;
  border-radius: 2px;
  background-color: #169c16;
  width: 70px;
  margin: 10px 0;
  color: white;
  cursor: pointer;
}
.addText:hover {
  background-color: #2776b9;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea name='textArea' class='textArea' rows="7" cols="50">Suspendisse convallis, metus at laoreet congue, sapien dui ornare magna, a porttitor felis purus a ipsum. Morbi vulputate erat rhoncus, luctus neque ut, lacinia orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis
  egestas. Fusce aliquam, nulla nec fringilla ultrices, ipsum lectus maximus nisl, ut laoreet purus lectus eget nisl. Duis blandit cursus nulla. Vestibulum consectetur, nunc non viverra condimentum, neque neque tincidunt diam, nec vestibulum neque nisi
  ac sem. Integer aliquam a leo id laoreet. Mauris ultrices mauris lorem, eu hendrerit odio volutpat ut. Nam eget hendrerit metus.</textarea>
<div class='addText'>
  Add Text
</div>
Run Code Online (Sandbox Code Playgroud)

测试:

  • FF:50
  • Chrome:55
  • 边缘38
  • Safari:5.1
  • 歌剧:42

  • 这不适用于FF 57(不再?) (3认同)
  • 显然,FF 现在会在操作该值时取消文本区域的撤消历史记录。FF 中有一个相关的错误报告,建议正确实现 insertText 命令:https://bugzilla.mozilla.org/show_bug.cgi?id=1220696 因此,希望我们可以在某个时候对所有浏览器简单地使用 insertText 命令未来。 (2认同)
  • 根据 MDN,execCommand() 现已弃用。请参阅相关/sf/ask/3113018961/#comment119939098_44473352 (2认同)

ale*_*lex 6

您需要以特殊方式插入文本,以便用户可以使用正常的撤消/重做行为.

var textEvent = document.createEvent('TextEvent');

textEvent.initTextEvent('textInput', true, true, null, "new text");

document.getElementById("your-textarea").dispatchEvent(textEvent);
Run Code Online (Sandbox Code Playgroud)

  • 根据Chrome的说法,这种方法很快就不再适用了:https://www.chromestatus.com/feature/57188​​03933560832 (3认同)
  • 我在哪里可以找到这方面的文件?我必须正确地搜索,因为我提出的很少. (2认同)
  • 今天停止在Chrome版本分支中工作。 (2认同)

Jos*_*ber 3

将 的原始值保存textarea在 its 中data

var $textarea = $('textarea');

$('button').on('click', function () {
    var val = $textarea.val();

    $textarea.data('old-val', val).val(val + ' some text');
});
Run Code Online (Sandbox Code Playgroud)

如果您想要一个数据数组(如 @ahren 建议的那样),请使用以下命令:

var $textarea = $('textarea');

$('button').on('click', function () {
    var val = $textarea.val();

    if ( ! $textarea.data('old-val')) {
        $textarea.data('old-val', []);
    }

    $textarea.data('old-val').push(val);

    $textarea.val(val + ' some text');
});
Run Code Online (Sandbox Code Playgroud)