JS - 将字母数字键盘 keyCode 映射到拨号盘号码 2 - 9

JS - Map alphanumeric keyboard keyCode to a dial pad number 2 - 9

我正在尝试创建一个拨号器小部件,捕获 "keydown" 事件并突出显示相应的拨号器号码。

因此,例如单击键盘上的 "A",会在 UI 上突出显示“2”:

我已经成功映射了前 5 位数字 (2-6)。因为它们每个包含 3 个字母,所以我能够像这样映射 keyCode:

Math.floor(((KeyCode - 65) / 3) + 2).

问:有没有办法在一行中完成,所以 PQRS 和 WXYZ 适合解决方案?

如果你真的需要它,那可能有用:

    Math.min(9, Math.floor(((KeyCode - (KeyCode < 83 ? 65 : 66)) / 3) + 2))

但您还必须确保 KeyCode 确实是一个字母。

您讨论的显而易见的解决方案要好得多,因为它可读、可配置并且执行速度同样快:

    function toDialNumber(KeyCode) {
      var keyMap = {1:"", 2:"ABC", 3:"DEF", 4:"GHI", 5:"JKL", 6:"MNO", 7:"PQRS", 8:"TUV", 9:"WXYZ"};
      var letter = String.fromCharCode(KeyCode);
      for(key in keyMap) if(keyMap[key].indexOf(letter)>=0) return key;
      return false;
    }

[A map] is the obvious solution, I'm looking into a math solution

如果您正在寻找一个分析表达式,您可以适合例如给定键码到数字映射的二次函数或指数函数:

// Exponential fit:
Math.floor(33.2 - 65.5 * Math.exp(-0.0115 * KeyCode));

或者,您可以通过比较运算符对出现在 keycode > 82 和 keycode > 89 处的 'anomalies' 进行编码。

// Comparison:
Math.floor((KeyCode - 65 - (KeyCode > 82) - (KeyCode > 89)) / 3 + 2);

指数拟合的优点是keycode项只出现一次,后面的表达式可读性更好。

实施/测试示例:

// Quadratic fit:
var sqr = (k) => -0.0018 * k * k + 0.59 * k - 28.6 | 0;

// Exponential fit:
var exp = (k) => 33.2 - 65.5 * Math.exp(-0.0115 * k) | 0;

// Comparison:
var cmp = (k) => (k - 65 - (k > 82) - (k > 89)) / 3 + 2 | 0;

for (var k = 65; k <= 90; ++k) {
  console.log(String.fromCharCode(k), sqr(k), exp(k), cmp(k));
}