首页 > 解决方案 > 使用 jQuery 的按键传递

问题描述

我正在尝试在 javascript/jQuery 中进行事件/字符传递,这基本上将按键事件的“执行”延迟了大约 2000 毫秒。我已经设置了一个处理程序来捕获所有按键事件并将它们放在缓冲区中。但是我无法“回放”存储在缓冲区中的按键序列。

它的工作方式(您将在片段中看到这一点)是点击“+”键开始缓冲。在您点击"+"之后,您点击的任何键都将存储到缓冲区中。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>

标签: javascriptjqueryhtmlkeypress

解决方案


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


推荐阅读