Javascript jQuery .keypress() 可以同时检测多个键吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4954403/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 14:56:33  来源:igfitidea点击:

Can jQuery .keypress() detect more than one key at the same time?

javascriptjquery

提问by Chris Abrams

Is there a way for jQuery to detect that more than one key was pressed at the same time?

有没有办法让 jQuery 检测到同时按下了多个键?

Is there any alternative that allows for pressing two keys at the same time to be detected?

是否有任何替代方法可以检测到同时按下两个键?

回答by David Tang

In order to detect multiple keys being held down, use the keydownand keyupevents.

为了检测被按住的多个键,请使用keydownkeyup事件。

var keys = {};

$(document).keydown(function (e) {
    keys[e.which] = true;
});

$(document).keyup(function (e) {
    delete keys[e.which];
});

I've put together a demo here: http://jsfiddle.net/gFcuU/. It's kind of fun, though I noticed my keyboard is only able to detect at most 6 keys.

我在这里整理了一个演示:http: //jsfiddle.net/gFcuU/。这很有趣,但我注意到我的键盘最多只能检测 6 个键。

回答by jAndy

It depends. For "normal" keys, that means Non- Shift, Ctrl, ALT, (CMD), the answer is no, the event handler will catch/fire in a queue, one after another.

这取决于。对于“正常”键,这意味着非ShiftCtrlALT,( CMD),答案是否定的,该事件处理程序将赶上/火在队列中,一个接一个。

For the modifier keys I mentioned above, there is a property on the event object.

对于我上面提到的修饰键,事件对象上有一个属性。

Example:

例子:

$(document).bind('keypress', function(event) {
    if( event.which === 65 && event.shiftKey ) {
        alert('you pressed SHIFT+A');
    }
});

Jsfiddle demo.

Jsfiddle 演示

Other propertys are:

其他属性是:

  • event.ctrlKey
  • event.altKey
  • event.metaKey
  • event.ctrlKey
  • event.altKey
  • event.metaKey

回答by Robert Alex Matevish

If you just want to fire a handler when several keys are pressed in series, try something like:

如果您只想在连续按下多个键时触发处理程序,请尝试以下操作:

jQuery.multipress = function (keys, handler) {
    'use strict';

    if (keys.length === 0) {
        return;
    }

    var down = {};
    jQuery(document).keydown(function (event) {
        down[event.keyCode] = true;
    }).keyup(function (event) {
        // Copy keys array, build array of pressed keys
        var remaining = keys.slice(0),
            pressed = Object.keys(down).map(function (num) { return parseInt(num, 10); }),
            indexOfKey;
        // Remove pressedKeys from remainingKeys
        jQuery.each(pressed, function (i, key) {
            if (down[key] === true) {
                down[key] = false;
                indexOfKey = remaining.indexOf(key);
                if (indexOfKey > -1) {
                    remaining.splice(indexOfKey, 1);
                }
            }
        });
        // If we hit all the keys, fire off handler
        if (remaining.length === 0) {
            handler(event);
        }
    });
};

For instance, to fire on s-t,

例如,向 st 开火,

jQuery.multipress([83, 84], function () { alert('You pressed s-t'); })

回答by Hastig Zusammenstellen

Here's a jQuery solution based on Maciej's answer https://stackoverflow.com/a/21522329/

这是基于 Maciej 回答的 jQuery 解决方案https://stackoverflow.com/a/21522329/

// the array to add pressed keys to
var keys = [];
// listen for which key is pressed
document.addEventListener('keydown', (event) => {
    if ($.inArray(event.keyCode, keys) == -1) {
        keys.push(event.keyCode);
    }
    console.log('keys array after pressed = ' + keys);
});
// listen for which key is unpressed
document.addEventListener('keyup', (event) => {
    // the key to remove
    var removeKey = event.keyCode;
  // remove it
    keys = $.grep(keys, function(value) {
        return value != removeKey;
    });
    console.log('keys array after unpress = ' + keys);
});
// assign key number to a recognizable value name
var w = 87;
var d = 68;
var s = 83;
var a = 65;
// determine which keys are pressed
document.addEventListener('keydown', (event) => {
  if ($.inArray(w, keys) != -1 && $.inArray(d, keys) != -1) { // w + d
    console.log('function for w + d combo');
  } else if ($.inArray(s, keys) != -1 && $.inArray(a, keys) != -1) { // s + a
    console.log('function for s + a combo');
  }
})

fiddle demo

小提琴演示

https://jsfiddle.net/Hastig/us00zdo6/

https://jsfiddle.net/Hastig/us00zdo6/

回答by Jacob Relkin

Nope. keypresswill fire for every individual key that is pressed - except for modifier keys such as CTRL, ALT and SHIFT, you cancombine them with other keys, so long as it is only one other key.

不。keypress将针对每个被按下的单个键触发 - 除了 CTRL、ALT 和 SHIFT 等修饰键之外,您可以将它们与其他键组合,只要它只是一个其他键。

回答by Maciej Paprocki

As my gist expired ( no one was using it :( ) I decided to update the answer with more 2017 solution. Check below.

随着我的要点过期(没有人使用它:()我决定用更多 2017 解决方案更新答案。检查下面。

You can use my plugin for jquery to detect shortcuts.

您可以使用我的 jquery 插件来检测快捷方式。

It basically cache's events and get what keys are pressed at the moment. If all the keys are pressed it fires function.

它基本上缓存的事件并获取此刻按下的键。如果按下所有键,则会触发功能。

https://github.com/maciekpaprocki/bindShortcut(expired!)

https://github.com/maciekpaprocki/bindShortcut(已过期!)

You have small explanation how to use it in readme file. Hope this helps. Feedback more than appreciated.

您对如何在自述文件中使用它有一些小说明。希望这可以帮助。反馈多于赞赏。

Edit 2017:

2017年编辑:

It's 2017 and we don't need jQuery plugins to solve stuff like that. In short you will need something like this:

现在是 2017 年,我们不需要 jQuery 插件来解决这样的问题。简而言之,您将需要这样的东西:

let pressed = {};

document.addEventListener('keydown', (event) => {
   pressed[event.key] = true;
});
document.addEventListener('keyup', (event) => {
   delete pressed[event.key];
});

//and now write your code
document.addEventListener('keydown', (event) => {
  if(pressed[firstKey]&&pressed[secondKey]){
    //dosomething
  }
});

Older browsers might have some quirks, however from IE9 everything should work fine except of marginal amounts of OSs that don't support right event delegation (super old ubuntu etc.). There's no way to fix that in them as that's not the browser issue.

较旧的浏览器可能有一些怪癖,但是从 IE9 开始,除了不支持正确事件委托的少量操作系统(超级旧的 ubuntu 等)之外,一切都应该正常工作。没有办法解决这个问题,因为这不是浏览器问题。

There are some quirks in new macs connected to boolean keys like for example caps lock.

连接到布尔键的新 Mac 中有一些怪癖,例如大写锁定。

Read more: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names_and_Char_values

阅读更多:https: //developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names_and_Char_values

回答by y?lmaz

According to @David Tang's solution, here is a quick and dirty customization for capturing Shift+Ctrl+A combination:

根据@David Tang 的解决方案,这是一个用于捕获 Shift+Ctrl+A 组合的快速而肮脏的自定义:

var pressedKeys = {};

function checkPressedKeys() {
    var shiftPressed=false, ctrlPressed=false, aPressed=false;
    for (var i in pressedKeys) {
        if (!pressedKeys.hasOwnProperty(i)) continue;
        if(i==16){
            shiftPressed=true;
        }
        else if(i==17){
            ctrlPressed=true;
        }
        else if(i==65){
            aPressed=true;
        }
    }
    if(shiftPressed && ctrlPressed && aPressed){
        //do whatever you want here.
    }
}


$(document).ready(function(){
    $(document).keydown(function (e) {
        pressedKeys[e.which] = true;
        checkPressedKeys();
    });

    $(document).keyup(function (e) {
        delete pressedKeys[e.which];
    });
});

回答by Fabio Sungurlian

If you're using esma6, you could do the following using sets.

如果您使用的是 esma6,则可以使用集合执行以下操作。

const KEYS = new Set();

$(document).keydown(function (e) {
   KEYS.add(e.which);
   if(KEYS.has(12) && KEYS.has(31)){
      //do something
   }
});
$(document).keyup(function (e) {
   KEYS.delete(e.which);
});

And if you want the user to press them together, you can do:

如果您希望用户将它们按在一起,您可以执行以下操作:

const KEYS = new Set(); // for other purposes
const RECENT_KEYS = new Set(); // the recently pressed keys
const KEY_TIMELAPSE = 100 // the miliseconds of difference between keys

$(document).keydown(function (e) {
   KEYS.add(e.which);
   RECENT_KEYS.add(e.which);
   setTimeout(()=>{
      RECENT_KEYS.delete(e.which);
   }, KEY_TIMELAPSE);
   if(RECENT_KEYS.has(37) && RECENT_KEYS.has(38)){
      // Do something
   }
});
$(document).keyup(function (e) {
   KEYS.delete(e.which);
   RECENT_KEYS.delete(e.which);
});

Here is a codepen https://codepen.io/Programador-Anonimo/pen/NoEeKM?editors=0010

这是一个代码笔https://codepen.io/Programador-Anonimo/pen/NoEeKM?editors=0010