JavaScript中检测按键序列

3
我有以上脚本,请查看Fiddle或以下。
<script type="text/javascript">
    function check(e){
        var text = e.keyCode ? e.keyCode : e.charCode;
                 
         switch(text){
         case 81:
            text = '&#4632;';
            break;
        case 87:
            text = '&#4633;';
            break;
        case 69:
            text = '&#4634;';
            break;
        case 82:
            text = '&#4635;';
            break;
        case 84:
            text = '&#4636;';
            break;
        case 89:
            text = '&#4637;';
            break;
        case 85:
            text = '&#4638;';
            break;
}
    
    if(text == 8){
        
        var str = document.getElementById("out").innerHTML;
        var foo = str.substring(0, str.length -1);
        document.getElementById("out").innerHTML = foo; 
    }else {
        document.getElementById("out").innerHTML += text;
    }

    }
    
</script>
<input  type='text'  onkeyup='check(event);' id='in' />
    
<div id='out' ></div>

只更改了一些 qwerty 字母,将其转换为其他的 Unicode 码。也就是说,每个字母都被转换为另一个字母,但问题在于有些字母只能通过两个键的组合来创建,无论是同时按下还是分别按下。

  1. 当你按下 m 然后迅速按下 o 时,它应该生成 x
  2. 或者当你按下 shift + p 时,它应该生成 y

这里的问题在于代码只能识别每次敲击一个字母。我已经尝试使用:

if(text == 77+79){  // this is for m + o
text 'x';
}

甚至是shift+p,应该输出z也是可以的。我尝试将上述论点内置,但它并没有起作用。


2
已经发布了,请尝试访问此链接:https://dev59.com/Ims05IYBdhLWcg3wDttn - JDGuide
1
检测按键序列(例如,先按下并释放 m 键,然后按下 o 键 => x)与检测按键组合(同时按下 shift + p)是两个不同的问题。如何实现这两个功能是完全不同的。后者似乎已经有了答案,正如 @JDeveloper 所指出的那样;你应该单独询问前者(也许已经有了答案)。 - doppelgreener
3个回答

3
听起来你想捕获“异常”的按键组合。为此,我认为您需要捕获和记录 keyupkeydown
你需要类似于这样的东西,但不一定完全相同...
var keysdown = {};
var lastkey = 0;

element.onkeyup = function(evt) {
  var e = evt || window.event;
  keysdown[e.keyCode ? e.keyCode : e.charCode] = true;
}

element.onkeyup = function(evt) {
  var e = evt || window.event;
  var code = e.keyCode ? e.keyCode : e.charCode;
  keysdown[code] = false;
  switch (code) {
    // for cases wherein you need to detect keyA + keyB
    case 77:
      if (keysdown[79]) {
        // x
      } else {
        // m
      }
      break;
    // for cases wherein you need to detect sequence A, B
    case B:
       if (lastkey == A) {
         // do A,B
       } else {
         // do B
       }
       break;
  }
  lastkey = code;
}

@kranzdot 我会马上做一个小程序... 给我一分钟。 - svidgen
@kranzdot 快速问题——您是否需要能够检测序列以及组合?还是,我的初步理解是正确的,即77和79 一起 会产生“x”? - svidgen
那将是非常棒的。是的,你说得对。但是,只有在77之后按下79时才会生效,而不是同时按下。 - user1236473
不要太担心它。 - user1236473
抱歉,我离开了一段时间。代码根本不起作用。我点击了键盘上的所有字母,但什么也没有显示出来。 - user1236473
@kranzdot 你想将所有原始字符回显到文本框中吗?...只需在onkeyup属性中将return false;更改为return true;即可。 - svidgen

0

你试过这个吗?:

if(text == 77 && text == 79){
    text 'x';
}

我不是同时按下两个键,而是一个接一个地按。因此,这涉及到一些时间控制。 - user1236473

0
在这个例子中,有像accd这样的2个键的组合,但你也可以有3个或更多键的组合,如agk
<!DOCTYPE html>
<html>

<head>
    <meta content="text/html; charset=UTF-8" http-equiv="content-type">
    <title>Example</title>
    <style type="text/css">
        td {
            width: 20px;
            height: 20px;
            text-align: center;
            vertical-align: middle;
        }
    </style>
    <script type="text/javascript" src="jquery-1.9.0.js"></script>
</head>

<body>

    <input type="text" />

    <script type="text/javascript">
        //IE 8 and below doesn't have addEventLisener but all other majon browser have it
        if (Element.prototype.addEventListener === undefined) {
            Element.prototype.addEventListener = function (eventName, callback) {
                var me = this;
                this.attachEvent("on" + eventName, function () {
                    callback.call(me, window.event);
                });
            }
        }
        var myApp = {
            multiChar: [
                [65, 67],//ac
                [67, 68] //cd
            ],
            prefChar: [0, 0], //Index of mutichar match
            replacers: ["مرحبا", "وداعا"], //replace multichar matches (ac with مرحبا) 
            checkCode: function (e) {
                var i = 0, inp;
                //IE probably doesn't have shiftkey or implements it differently
                if (e.shiftKey) {
                    //check stuff with shift
                    console.log("with shift", e.keyCode);
                    //If a match found then reset prefChar
                    prefChar = [0, 0];
                    return;
                }
                for (i = 0; i < myApp.multiChar.length; i++) {
                    if (e.keyCode !== myApp.multiChar[i][myApp.prefChar[i]]) {
                        myApp.prefChar[i] = (e.keyCode === myApp.multiChar[i][0]) ? 1 : 0
                        continue
                    }
                    myApp.prefChar[i]++;
                    if (myApp.prefChar[i] === myApp.multiChar[i].length) {
                        // found a multichar match
                        console.log(myApp.replacers[i]);
                        inp = document.body.getElementsByTagName("input")[0];
                        inp.value = inp.value.substr(
                            0, inp.value.length - myApp.multiChar[i].length) +
                            myApp.replacers[i];
                        myApp.prefChar[i] = 0;
                        return;
                    }
                }
            }
        }
        document.body.getElementsByTagName("input")[0]
            .addEventListener("keyup", myApp.checkCode);
    </script>


</body>

</html>

目前它不会替换任何东西,只是在控制台中输出检测结果。已对代码进行更改,以便于 aaac 中的 ac 部分也能被检测到。 - HMR
新答案替换它。使用正则表达式可能会更容易些。 - HMR
非常感谢,但代码似乎很复杂,你能指导我去哪个教程可以帮助我记录按键吗? - user1236473
它主要依赖于数组,multiChar包含一系列的数组,因此mutiChar[0]包含2个值(a和c的字符代码或[65,67])。prefchar包含multiChar子数组的索引,所以如果用户键入了a,则prefChar是[1,0],因为a匹配字符代码[0][0]中的keycode 65。如果我接下来输入c,则会匹配charCode [0] [1](即67)。使用多维数组有点复杂,而且当您需要返回代码并进行更改时,始终难以维护或更改,但它非常适合解决这个特定的问题。 - HMR
以下是 JavaScript 的好参考资料:https://developer.mozilla.org/en/docs/JavaScript/Reference - HMR
不想挑剔,但请考虑回答时简短明了。前14行完全没有用。 - Martin James

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接