Сквозное нажатие клавиш с использованием jQuery

Я пытаюсь сделать передачу события / символа в 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>

Мне действительно любопытно, почему вы пытаетесь это сделать ...

fubar 15.05.2018 04:57

Свайпер карты. Мой клиент хочет иметь возможность провести магнитную карту в любой момент (даже сразу после редактирования текстового поля). Карточки имеют шаблон, который начинается с "+" и заканчивается новой строкой (Enter) char.

Matt Spinks 15.05.2018 05:00

На самом деле я установлю этот интервал около 200 мс (вместо 2000 мс). Сейчас я использую 2000 мс, чтобы было легче отлаживать.

Matt Spinks 15.05.2018 05:03

Интересно, ладно. Почему вы специально хотите «воспроизвести» события нажатия клавиш, а не просто устанавливать для input.value любое значение stringBuffer?

fubar 15.05.2018 05:06

Мой клиент может редактировать текстовое поле, и изменения могут включать символ «+» где-то в середине текстового поля. И если это произойдет, сначала будет запущена буферизация. Если "Enter" не нажимается в течение 2000 мс (на самом деле 200 мс), я хочу, чтобы все происходило нормально, как если бы буферизация не была включена.

Matt Spinks 15.05.2018 05:11

Это сложно. Я в основном ищу последовательность нажатий клавиш за очень короткий период времени. Если я найду этот шаблон, я не хочу, чтобы символы появлялись в полях ввода. Но если я не найду шаблон, я хочу, чтобы символы отображались в полях ввода.

Matt Spinks 15.05.2018 05:14

@fubar: Я вообще ничего не вижу в текстовом поле.

Matt Spinks 15.05.2018 05:45

Извини за это. Вот этот лучше?

fubar 15.05.2018 06:33
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
8
446
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю, вы можете просто использовать свой строковый буфер, если воспользуетесь 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» следует вставить туда, где находится курсор. И курсор может быть в конце, а может быть где-то посередине.

Matt Spinks 15.05.2018 05:44

Выглядит неплохо. В итоге я использовал это. Тем не менее, я сделал несколько модов. Мне нужно было вставить текст в каретку. Но это дало мне отличное начало.

Matt Spinks 17.05.2018 16:04

Другие вопросы по теме