jQuery .keypress()可以同时检测多个密钥吗?

时间:2011-02-10 07:18:51

标签: javascript jquery

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

是否有任何替代方案可以同时按下两个键?

8 个答案:

答案 0 :(得分:73)

要检测按下的多个键,请使用keydownkeyup个事件。

var keys = {};

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

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

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

答案 1 :(得分:51)

这取决于。对于“普通”键,这意味着非 Shift Ctrl ALT ,( CMD ),答案如果不是,事件处理程序将一个接一个地捕获/触发队列。

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

示例:

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

Jsfiddle demo

其他特性是:

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

答案 2 :(得分:2)

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

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);
        }
    });
};

例如,要点击s-t,

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

答案 3 :(得分:1)

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

答案 4 :(得分:1)

这是一个基于的jQuery解决方案 Maciej的回答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');
  }
})

小提琴演示

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

答案 5 :(得分:0)

由于我的要点已经过期(没有人使用它:()我决定用更多的2017解决方案更新答案。请查看以下内容。

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

它基本上缓存了事件并获取了当前按下的键。如果按下所有键,它将触发功能。

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

您在自述文件中有如何使用它的小解释。希望这可以帮助。反馈超过赞赏。

编辑2017:

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
  }
});

旧的浏览器可能有一些怪癖,但是从IE9开始,一切都应该可以正常工作,除了边缘数量的操作系统不支持正确的事件委托(超级旧的ubuntu等)。由于这不是浏览器问题,因此无法解决这些问题。

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

了解详情:https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names_and_Char_values

答案 6 :(得分:0)

根据@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];
    });
});

答案 7 :(得分:0)

如果您使用的是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);
});

如果您希望用户将它们同时按下,则可以执行以下操作:

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);
});

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