Когда клавиша CMD удерживается нажатой, клавиатура не запускается для любого другого ключа

Я разрабатываю приложение, где мне нужно выполнить некоторую пост-обработку, когда пользователь нажимает CMD + LEFT в определенном текстовом поле. Мне нужно сделать это после функциональности браузера по умолчанию (т.е. После того, как каретка займет первую позицию в текущей физической строке).

Проблема заключается в том, что keyup не работает не для клавиши LEFT (или любой другой клавиши), если клавиша CMD не работает.

Я пробовал это с помощью клавиш CTRL и SHIFT и обнаружил, что активация ключа запускается, как ожидалось, для вторичного ключа. Поэтому, если вы выполняете CTRL + LEFT, а затем отпустите LEFT, а затем отпустите CTRL, вы получите четыре события в общей сложности, 2 нажатия клавиш и 2 клавиши. Тем не менее, для CMD-ключа мы получаем 2 keydowns, но только одно событие keyup (одно для самого CMD-ключа, когда мы его выпускаем в конце).

Я попробовал это с помощью SHIFT-ключа и обнаружил, что keyup запускается, как ожидалось, для вторичного ключа. Итак, если вы делаете SHIFT + LEFT, а затем отпустите LEFT, а затем отпустите SHIFT, вы получите всего 4 события, 2 нажатия клавиш и 2 клавиши. Тем не менее, для CMD-ключа мы получаем 2 keydowns, но только одно событие keyup (первое для CMD-ключа, когда мы его выпускаем в конце).

Что это может быть? Есть ли способ, по которому я могу получить keyup для клавиши LEFT (или любой клавиши), когда CMD опущен?

Я пробую это с последним Google Chrome на OSX 10.9.5. Поведение точно так же и в Firefox. Так что это не проблема Chrome.

Демо: http://jsfiddle.net/techfoobar/xu0o11nh/4/

По существу:

$('#mytextbox')

    // this gets correctly triggered for the meta key as well as the secondary key
    // when you press CMD and LEFT in sequence, you get two lines in the console one for 
    // the CMD key and one for the LEFT key
    .keydown(function(_e) {
        console.log('Keydown: ' + _e.keyCode);
    })

    // however, if I release the LEFT key (while keeping the CMD key down)
    // this does NOT get triggered for the LEFT key
    .keyup(function(_e) {
        console.log('Keyup: ' + _e.keyCode);
    });

Ответы

Ответ 1

Это известное поведение с мета-ключом, и, к сожалению, не существует известного способа обхода.

В вашем случае вы можете самостоятельно рассмотреть поведение браузера по умолчанию (как это сделать), а затем реализовать нужное поведение и завершить его с помощью _e.preventDefault();

Ответ 2

Это почти наверняка связано с системными наборами "горячих клавиш". Очевидно, согласно документам это отсутствующее событие keyup равно ожидаемому поведению.

Когда я делаю cmd space, я даже не получаю событие keydown для space, когда появляется окно прожектора.

По поводу упоминания клавиши ctrl: потому что у меня есть "пробелы", когда я ctrl left или ctrl right я не получаю никаких левых или правых событий смены ключа, однако ctrl up или ctrl down, по крайней мере, запускают свои события смены ключа.

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

Ответ 3

Не думайте, что вам понадобится настройка.

Я изменил код, чтобы обнаружить 2 нажатия клавиш. это может быть реорганизовано далее в более чистый код.

http://jsfiddle.net/7nd7hf16/1/

var cmdDown = false;
$('#foo')
.keydown(function(_e) {
    if(_e.keyCode == 91)
        cmdDown = true;

    if(cmdDown && _e.keyCode == 37)
        console.log('cmd + left'); 

    console.log('Keydown: ' + _e.keyCode);
})
.keyup(function(_e) {
    if(_e.keyCode == 91)
        cmdDown = false;

    console.log('Keyup: ' + _e.keyCode);
})
.focus();