使用 jQuery 的按键传递

Keypress pass-through using jQuery

我正在尝试在 javascript/jQuery 中进行 event/character 传递,这基本上会延迟按键事件的 "actuating" 大约 2000 毫秒。我已经设置了一个处理程序来捕获所有按键事件并将它们放入缓冲区。但是我在 "playing back" 缓冲区中存储的按键序列时遇到了问题。

它的工作方式(您将在代码片段中看到)是按下 "+"+" 键开始缓冲。在您点击 "+" 之后,您之后点击的任何键都会存储到缓冲区中。 2000 毫秒后,缓冲关闭。如果您在点击 "+"+" 后的 2000 毫秒内点击 "Enter",那么缓冲区将被清空(我正在那里做其他事情在我的真实代码中)。但是,如果您没有在 2000 毫秒内点击 "Enter",则需要回放按键。这就是我遇到的问题。

播放 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>

我认为如果您利用 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>