Может ли jQuery .keypress () обнаруживать более одного ключа одновременно? - PullRequest
45 голосов
/ 10 февраля 2011

Есть ли способ для jQuery обнаружить, что более чем одна клавиша была нажата одновременно?

Есть ли альтернатива, позволяющая одновременно обнаружить две клавиши?

Ответы [ 8 ]

75 голосов
/ 10 февраля 2011

Чтобы обнаружить несколько нажатых клавиш, используйте события keydown и keyup.

var keys = {};

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

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

Я собрал здесь демонстрацию: http://jsfiddle.net/gFcuU/. Это забавно, хотя я заметил, что моя клавиатура способна распознавать не более 6 клавиш.

54 голосов
/ 10 февраля 2011

Это зависит.Для «обычных» клавиш это означает, что не- 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
3 голосов
/ 17 февраля 2015

Если вы просто хотите запустить обработчик при последовательном нажатии нескольких клавиш, попробуйте что-то вроде:

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'); })
2 голосов
/ 03 января 2018

Вот решение 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');
  }
})

демонстрация скрипки

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

2 голосов
/ 10 февраля 2011

Неа. keypress будет срабатывать для каждой отдельной нажатой клавиши - за исключением клавиш-модификаторов, таких как CTRL, ALT и SHIFT, вы можете комбинировать их с другими клавишами, если это только одна другая клавиша.

0 голосов
/ 17 февраля 2019

Если вы используете 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);
});

Вот кодекс https://codepen.io/Programador-Anonimo/pen/NoEeKM?editors=0010

0 голосов
/ 06 января 2019

В соответствии с решением @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];
    });
});
0 голосов
/ 03 февраля 2014

Поскольку моя сущность истекла (никто не использовал ее :(), я решил обновить ответ с помощью решения 2017 года. Проверьте ниже.

Вы можете использовать мой плагин для jquery, чтобыобнаружение горячих клавиш.

Это в основном кеширование событий и получение того, какие клавиши были нажаты в данный момент. Если все клавиши нажаты, запускается функция.

https://github.com/maciekpaprocki/bindShortcut (истек срок действия!)

У вас есть небольшое объяснение, как использовать его в файле readme. Надеюсь, это поможет. Обратная связь более чем оценена.

Редактировать 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 и т. Д.). В них невозможно исправить это, поскольку это не проблема браузера.

В новых маках, связанных с булевыми ключами, есть некоторые причуды, такие какзапример блокировки шапки.

Подробнее: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names_and_Char_values

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...