三键 keyCode 热键 javascript

three button keyCode hotkey javascript

来自另一个 stackoverflow 帖子(如何将 JavaScript 键盘快捷键添加到现有 JavaScript 函数?)我有这个热键代码:

1
2
3
4
5
6
7
function doc_keyPress(e) {
    if (e.shiftKey && e.keyCode == 80) {
       //do something
    }
}

document.addEventListener('keyup', doc_keyPress, false);

使用两个键。但是使用三个键,例如 shift l m,它不起作用。

if 语句是:

1
if (e.shiftKey && e.keyCode == 76 && e.keyCode == 77) {}

再一次,这不起作用。

我如何让这个工作为 shift l m.


棘手,棘手,但我设法让它工作。请注意,浏览器有自己的热键(如 chrome [ctrl] [shift] i),它可能会覆盖该功能。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!DOCTYPE html>
<html>
<body>
<input id="myInput" onkeydown="keyDownEvent(event)" onkeyup="resetKeys()">
</body>
</html>

var key1Pressed=false;
var key2Pressed=false;

function resetKeys(){
    key1Pressed=false;
    key2Pressed=false;
}
function keyDownEvent(e){
    e=e||event, chrCode=(typeof e.which=="number")?e.which:e.keyCode;

    if (e.shiftKey && chrCode === 76) key1Pressed=true;
    if (e.shiftKey && chrCode === 77) key2Pressed=true;

    if(key1Pressed && key2Pressed){

        alert('Three Keys Are Pressed');

        key1Pressed=false;
        key2Pressed=false;
    }
}

document.getElementById('myInput').focus();

使用闭包,我想你可以做这样的事情

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
var doc_keypress = (function() {
    var prevWasL = false;
    return function(e) {
        if (e.type == 'keypress') {
            if (e.shiftKey && !(e.ctrlKey || e.metaKey)) {
                if (prevWasL) {
                    if (e.charCode == 77) {
                        console.log('doing it');
                        prevWasL = false;
                        return;
                    }
                }
                if (e.charCode == 76) {
                    prevWasL = true;
                    return;
                }
            }
            prevWasL = false;
        } else { // keyup
            if (e.key == 'Shift') {
                prevWasL = false;
            }
        }
    }
}());

document.addEventListener('keypress', doc_keypress);
document.addEventListener('keyup', doc_keypress);

同时添加 keypress 和 keyup 事件侦听器,以便

的场景

Shift L,同时释放,Shift M,不会触发误报

这需要 shift 然后按 L 然后按 M 的顺序...如果你想要 L 和 M 的任何一个顺序,那么代码会有点不同,但你应该能够弄清楚

NOTE: I use charCode, because firefox at least, keyCode is always 0 on keyPress event


如果您尝试双击或三次按键并在此之后捕获事件,我已经编写了一个简单的帮助程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
function KeyPress(_opts) {
  this.opts = Object.assign({}, {
    counts: {},
    timeouts: {},
    timeBetweenPresses: 300
  }, _opts || {});
}

KeyPress.prototype.bubbledReset = function bubbledReset(keyCode) {
  var self = this;
  if (this.opts.timeouts[keyCode]) {
    clearTimeout(this.opts.timeouts[keyCode]);
    this.opts.timeouts[keyCode] = 0;
  }
  this.opts.timeouts[keyCode] = setTimeout(function () {
    self.opts.counts[keyCode] = 0;
  }, this.opts.timeBetweenPresses);
};

KeyPress.prototype.onTap = function onTap(cb) {
  var self = this;
  return function handler(event) {
    self.opts.counts[event.keyCode] = self.opts.counts[event.keyCode] || 0;
    self.opts.counts[event.keyCode]++;
    self.bubbledReset(event.keyCode);
    cb(event.keyCode, self.opts.counts[event.keyCode]);
  };
};

用法
只需使用 onTap 方法实例化:

1
2
3
4
5
6
7
8
9
10
var keyPress = new KeyPress();

document.addEventListener('keyup', keyPress.onTap(function (keyCode, count) {
  if (keyCode === 68 && count === 3) {
    // 68 was tapped 3 times (D key)
  }
  if (keyCode === 13 && count === 6) {
    // 13 was tapped 6 times (ENTER key)
  }
}));

希望这对其他人有帮助!

或者如果你喜欢 es6:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class KeyPress {
  constructor(_opts) {
    this.opts = Object.assign({}, {
      counts: {},
      timeouts: {},
      timeBetweenPresses: 300
    }, _opts || {});
  }

  bubbledReset(keyCode) {
    if (this.timeouts[keyCode]) {
      clearTimeout(this.timeouts[keyCode]);
      this.timeouts[keyCode] = 0;
    }
    this.timeouts[keyCode] = setTimeout(() => {
      this.counts[keyCode] = 0;
    }, this.timeBetweenPresses);
  }

  onTap(cb) {
    return event => {
      this.counts[event.keyCode] = this.counts[event.keyCode] || 0;
      this.counts[event.keyCode]++;
      this.bubbledReset(event.keyCode);
      cb(event.keyCode, this.counts[event.keyCode]);
    };
  }

}