Я пытаюсь сделать передачу события / символа в javascript / jQuery, которая в основном задерживает «срабатывание» события нажатия клавиши примерно на 2000 мс. Я установил обработчик для захвата всех событий нажатия клавиш и помещения их в буфер. Но у меня возникают проблемы с "воспроизведением" последовательности нажатий клавиш, хранящейся в буфере.
Как это работает (и вы увидите это во фрагменте), нажатие клавиши "+" запускает буферизацию. После того, как вы нажмете "+", любые клавиши, которые вы нажмете после этого, сохранятся в буфере. А через 2000 мс буферизация отключается. Если вы нажмете "Входить" в течение 2000 мс после нажатия "+", то буфер будет очищен (и я делаю что-то еще в моем реальном коде). Но если вы не нажмете «Enter» в течение 2000 мс, то нажатия клавиш необходимо воспроизвести. И вот где у меня проблема.
При воспроизведении keyBuffer я хочу, чтобы символы (которые должны возникать в результате нажатия клавиши) появлялись в любом элементе управления вводом, в котором находится пользователь (в месте курсора). Но когда я запускаю события, ничего не появляется. Возможно, я делаю это совершенно неправильно, но я не уверен. Я также сохраняю строку символов, которая совпадает с keyBuffer (хранится в stringBuffer, на случай, если я могу использовать строку для вставки символов (вместо воспроизведения нажатий клавиш). Но проблема в том, что я не знаю, какой ввод контроль, в котором может находиться пользователь.
Есть ли способ изменить мой код (ниже), чтобы события нажатия клавиш, которые я программно запускаю (в моем цикле), заставляли символы отображаться в сфокусированном элементе управления вводом?
var checkForSwipe = false;
var stringBuffer = '';
var keyBuffer = [];
$('body').keypress(function (e) {
var charCode = (e.which) ? e.which : e.keyCode
if (charCode == 43) { // "+"
//ENABLE KEY BUFFERING:
e.preventDefault();
e.stopPropagation();
checkForSwipe = true;
stringBuffer = '';
keyBuffer = [];
//AFTER A SET INTERVAL, IF ENTER HAS NOT BEEN PRESSED, THEN REPLAY THE KEYPRESSES:
setTimeout(function () {
checkForSwipe = false;
//REPLAY THE STORED KEYPRESSES:
if (keyBuffer && keyBuffer.length) {
$('#monitor').append('<b>Enter not pressed. Replaying keypresses:</b><br/>');
for (var i in keyBuffer) {
var which = keyBuffer[i]
var press = jQuery.Event("keypress");
press.ctrlKey = false;
press.which = which;
if (which != 43) {
$('#monitor').append(' ' + which + ' ');
$("body").trigger(press);
}
}
}
stringBuffer = '';
keyBuffer = [];
}, 2000);
}
if (e.keyCode == 13) { // "Enter"
if (checkForSwipe) {
e.preventDefault();
e.stopPropagation();
checkForSwipe = false;
stringBuffer += String.fromCharCode(charCode);
keyBuffer.push(e.which);
//DO SOMETHING WITH THE stringBuffer...
//THEN RESET:
stringBuffer = '';
keyBuffer = [];
}
}
//IF "+" HAS BEEN PRESSED IN THE INTERVAL, STORE THE KEYS IN THE BUFFER:
if (checkForSwipe) {
e.preventDefault();
e.stopPropagation();
stringBuffer += String.fromCharCode(charCode);
keyBuffer.push(e.which);
}
});#monitor {
background-color:#222;
color:#fff;
min-height:100px;
max-height:300px;
overflow:auto;
padding:4px;
}<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id = "i1" />
<input id = "i2" />
<input id = "i3" />
<input id = "i4" />
<input id = "i5" />
<div id='monitor'></div>Свайпер карты. Мой клиент хочет иметь возможность провести магнитную карту в любой момент (даже сразу после редактирования текстового поля). Карточки имеют шаблон, который начинается с "+" и заканчивается новой строкой (Enter) char.
На самом деле я установлю этот интервал около 200 мс (вместо 2000 мс). Сейчас я использую 2000 мс, чтобы было легче отлаживать.
Интересно, ладно. Почему вы специально хотите «воспроизвести» события нажатия клавиш, а не просто устанавливать для input.value любое значение stringBuffer?
Мой клиент может редактировать текстовое поле, и изменения могут включать символ «+» где-то в середине текстового поля. И если это произойдет, сначала будет запущена буферизация. Если "Enter" не нажимается в течение 2000 мс (на самом деле 200 мс), я хочу, чтобы все происходило нормально, как если бы буферизация не была включена.
Это сложно. Я в основном ищу последовательность нажатий клавиш за очень короткий период времени. Если я найду этот шаблон, я не хочу, чтобы символы появлялись в полях ввода. Но если я не найду шаблон, я хочу, чтобы символы отображались в полях ввода.
@fubar: Я вообще ничего не вижу в текстовом поле.
Извини за это. Вот этот лучше?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я думаю, вы можете просто использовать свой строковый буфер, если воспользуетесь activeElement. Просто нужно убрать ведущий "+".
Вы можете использовать selectionStart, чтобы определить, где в строке нужно вставить текст.
var checkForSwipe = false;
var stringBuffer = '';
var keyBuffer = [];
$('body').keypress(function (e) {
var charCode = (e.which) ? e.which : e.keyCode
if (charCode == 43) { // "+"
//ENABLE KEY BUFFERING:
e.preventDefault();
e.stopPropagation();
checkForSwipe = true;
stringBuffer = '';
keyBuffer = [];
//AFTER A SET INTERVAL, IF ENTER HAS NOT BEEN PRESSED, THEN REPLAY THE KEYPRESSES:
setTimeout(function () {
checkForSwipe = false;
//REPLAY THE STORED KEYPRESSES:
if (keyBuffer && keyBuffer.length) {
$('#monitor').append('<b>Enter not pressed. Replaying keypresses:</b><br/>');
var currentText = document.activeElement.value;
var currentIndx = document.activeElement.selectionStart;
var newText = currentText.slice(0, currentIndx) + stringBuffer.substr(1) + currentText.slice(currentIndx,currentText.length);
document.activeElement.value = newText;
}
stringBuffer = '';
keyBuffer = [];
}, 2000);
}
if (e.keyCode == 13) { // "Enter"
if (checkForSwipe) {
e.preventDefault();
e.stopPropagation();
checkForSwipe = false;
stringBuffer += String.fromCharCode(charCode);
keyBuffer.push(e.which);
//DO SOMETHING WITH THE stringBuffer...
//THEN RESET:
stringBuffer = '';
keyBuffer = [];
}
}
//IF "+" HAS BEEN PRESSED IN THE INTERVAL, STORE THE KEYS IN THE BUFFER:
if (checkForSwipe) {
e.preventDefault();
e.stopPropagation();
stringBuffer += String.fromCharCode(charCode);
keyBuffer.push(e.which);
}
});#monitor {
background-color:#222;
color:#fff;
min-height:100px;
max-height:300px;
overflow:auto;
padding:4px;
}<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id = "i1" />
<input id = "i2" />
<input id = "i3" />
<input id = "i4" />
<input id = "i5" />
<div id='monitor'></div>Это близко. Это может быть то, что я ищу. Однако курсор может находиться в середине длинной текстовой строки при нажатии «+». И если это произойдет, весь остальной текст будет очищен и заменен буфером. Буфер должен вставить текст туда, где находится курсор. Например, в коде введите «abc», затем нажмите «+» и сразу же введите «def». «Abc», который вы ввели первым, заменяется на «def». «Def» следует вставить туда, где находится курсор. И курсор может быть в конце, а может быть где-то посередине.
Выглядит неплохо. В итоге я использовал это. Тем не менее, я сделал несколько модов. Мне нужно было вставить текст в каретку. Но это дало мне отличное начало.
Мне действительно любопытно, почему вы пытаетесь это сделать ...