我有一个textarea和一个按钮。单击该按钮可将文本插入文本区域。
有没有办法允许用户按Ctrl / Cmd + z撤消文本的插入并将textarea恢复到以前的状态?
首先添加html,然后您可以使用按键事件进行撤消
你也可以在这里尝试http://jsfiddle.net/surendra786/1v5jxaa0/
<input type="text" class="reset actor_input" name="actor" value="add actors"></input>
<input type="text" name="actors"></input>
<div class="found_actors"></div>
<div id="add" class="button_content">ADD</div>
<div id="undo" class="button_content">UNDO</div>
<div class="actors_list"><textarea readonly style="resize: none;" rows="20" cols="20" name="actors-list"></textarea></div>
</div>
**然后添加jquery **
var items = [];
$("#add").click(function() {
// Push the new actor in the array
items.push($("[name='actor']").val());
populate();
});
$(document).keydown(function(e){
if( e.which === 90 && e.ctrlKey ){
console.log('control + z');
if (items.length > 0) {
// remove last element of the array
items.splice(-1,1);
populate();
}
}
});
populate = function() {
$("[name='actors-list']").text('');
$("[name='actors-list']").append(items.join(' '));
$("[name='actors']").val(items.join(','));
}
你可以试试http://jsfiddle.net/surendra786/1v5jxaa0/
这对我有用
这里有很多适用的答案可以满足您的需求。这是我在你的环境中会做的事情。这允许更改您最有可能使用的文本变量,您可以设置它,或者用户可以使用其他字段设置它等。
它的主旨就是这样的。
$(document).ready(function(){
function deployText(){
var textArray = [];
var textToAdd = 'let\'s go ahead and add some more text';
var textarea = $('textarea');
var origValue = textarea.text();
textArray.push(origValue);
$('button').on('click', function(e){
textArray.push(textToAdd);
textarea.text(textArray);
console.log(textArray.length);
console.log(textArray);
});
$(document).on('keypress', function(e){
var zKey = 26;
if(e.ctrlKey && e.which === zKey){
removePreviousText();
}
})
function removePreviousText(){
console.log(textArray);
if(textArray.length > 1){
textArray.pop();
$('textarea').text(textArray);
}
}
}
deployText()
})
这是一个简短的非jQuery解决方案,也适用于Firefox(无论如何都无法撤消)
// Solution
function insertText(textarea, text) {
// https://stackoverflow.com/a/55174581/288906
if (!document.execCommand('insertText', false, text)) {
textarea.setRangeText(text);
}
}
// Demo code to add text on click
const textarea = document.querySelector('textarea');
textarea.onclick = () => insertText(
textarea,
'@'
);
<textarea>Click in here to add text</textarea>
我还把它打包成npm module,提高了浏览器的一致性。
$("#target").keypress(function(event) {
if ( event.which == 'Z' && first press == 'Cmd' && second press == 'Ctrl') {//check for key press
event.preventDefault();
text.value = defaultValueForTextField
}
});
这应该是你正在寻找的。第一次和第二次按下需要保存,因为您需要组合印刷机。您确实需要保存默认文本值。
这是一个想法:
如果我们可以生成keyborad事件,就像用户在textarea中输入一样,那么浏览器将自动处理撤消事件。因此,我们应该尝试为我们要插入的文本模拟键盘事件,而不是仅仅添加/更改textarea的值。
根据MDN的文档(下面给出的链接),我们可以使用KeyboardEvent
对象生成如下事件:
var e1 = new KeyboardEvent(<type>, <details>);
var b1 = <textbox>.dispatchEvent(e1);
哪里:
<type>
代表事件类型,如keydown
,keypress
或keyup
<details>
代表具有事件细节的对象,如key
,code
<textbox>
表示我们想要触发事件的目标文本框这是一个JSFiddle,我试图模拟给定字符串中每个字符的keydown
,keypress
和keyup
事件。虽然它触发了相应的事件处理程序,但不知何时字符不会显示/添加到文本框中。
我注意到当我使用我的代码模拟a
的3个事件时,在文本框中键入a
时生成的事件对象存在一些差异。差异是(在Firefox 50.1.0中测试时):
explicitOriginalTarget
与originalTarget
不同;当我输入文本框时,它们都具有相同的值rangeParent
和rangeOffset
值是null
/ 0
;当我模拟事件时,他们有一些价值观isTrusted
属性是true
;当我模拟事件时它的false
(对于使用脚本生成的任何事件,它将有false
)MDN链接:
即使这个问题是一年前的问题,我也希望分享我的方式。
你可以这样做:
$(function () {
// Check to see if an array is not already defined.
if (!$('#t').data('old-val')) {
// If the check returns True we proceed to create an array in old-val.
$('#t').data('old-val', []);
}
// Get the current content value.
inputValue = $('#t').val();
// Push it to the old-val array.
$('#t').data('old-val').push(inputValue);
// We start with a current array position of 0.
curArrPos = 0;
$('#c').click(function () {
// Append a string to the #t.
$('#t').val(' ==this is the 2nd appended text==');
// Save the current content value.
inputValue = $('#t').val();
// Push it to the array.
$('#t').data('old-val').push(inputValue);
// Increment current array position.
++curArrPos;
});
$('#b').click(function () {
// Append a string to the #t.
$('#t').val(' ==this is the 1st appended text==');
// Save the current content value.
inputValue = $('#t').val();
// Push it to the array.
$('#t').data('old-val').push(inputValue);
// Increment current array position.
++curArrPos;
});
$('#undo').click(function () {
// First check that the old-val array length is greater than 1 (It's the initial position. No need undoing to a blank state) and current array position greater than 0 (for the same reason).
if ($('#t').data('old-val').length > 1 && curArrPos > 0) {
// Set current #t value to the one in the current array position, minus one.
// Minus one gets you to the previous array position (ex. current=5; previous= current - 1 = 4).
$('#t').val($('#t').data('old-val')[curArrPos - 1]);
// Decrease current array position, because we effectively shifted back by 1 position.
--curArrPos;
}
});
$('#redo').click(function () {
if (currentArrayPos < $('#c').data('old-val').length - 1) {
$('#t').val($('#t').data('old-val')[curArrPos + 1]);
// Increase current array position, because we effectively shifted forward by 1 position.
++curArrPos;
}
});
});
如果你想试试http://jsfiddle.net/45Jwz/1/,这是一个小提琴
我编写了这样的代码以便于理解,但是你当然应该更好地编写实际的代码并且比这更简洁。
具体的库和技术在很大程度上取决于您的堆栈。
我可以通过两种常规方式立即思考。
第一步:将以前的状态保存在控制器中。挂钩快捷方式并将内容替换为以前的状态。如果进行了其他修改,请删除钩子。或多或少你的2013年方法
这是一种快速的方法,如果您想要一个具有一次以上编辑历史记录的堆栈,则不会很好。
第二:观察textinput并定期将状态保存在堆栈中。钩入快捷方式。 (接管整个过程)。这是一种更简洁的方法,因为您的修改在概念上与用户修改相同。
使用redux / flux架构http://redux.js.org/docs/recipes/ImplementingUndoHistory.html,这可能非常简单
要捕获cmd / ctrl + z,你可以查看https://github.com/madrobby/keymaster
如果你详细说明你的堆栈/要求,我很乐意扩展这个答案。
最简单的方法似乎是:
现在:
$('#idOfTextarea').val($('#idOfTextarea').attr('prevContents'));
。撤消例程也会清除“脏”属性,以便不会调用撤消两次。你可能想要或不想在textarea上拦截onChange。如果onChange触发并且未设置脏,则这是初始按钮单击,可能会被忽略。否则,它可能表示用户已将其自己的一些更改添加到单击的文本中。在这种情况下,您可能希望禁用撤消以保留这些更改,或要求用户进行确认。
你可以这样做,
HTML
<div id="text-content">
<textarea rows="10" cols="50"></textarea>
<input type="button" name="Insert" value="Insert" />
</div>
jQuery的
var oldText = [],ctrl=false;
$(function(){
$("input[name=Insert]").click(function(){
var text = oldText.length+1;
oldText.push(text);
var textAreaText = $('textarea').val();
textAreaText +=text;
$('textarea').val(textAreaText);
$("input[name=insertText]").val('');
});
$('textarea').keydown(function(e){
if(e.which == 17){ ctrl = true;}
});
$('textarea').keyup(function(e){
var c = e.which;
if(c == 17){ ctrl = false;}
if(ctrl==true && c==90 ){
oldText.pop();
var text = '';
$.each(oldText,function(i,ele){
text += ele;
});
$('textarea').val(text);
}
})
})
您还可以检查并试验fiddle。