Обнаружение нажатых клавиш-модификаторов без запуска событий клавиатуры или мыши

Мое приложение меняет свое состояние, когда человек держит ключи-модификаторы (Shift, Alt, Ctrl). Я отслеживаю ключи-модификаторы с помощью событий keydown/keyup:

var altPressed;
window.onkeydown = window.onkeyup = function(e) {
    altPressed = e.altKey;
}

События клавиатуры не запускаются за пределами вкладки браузера. Теперь представьте себе следующий сценарий:

  • Удерживать клавишу Shift
  • Нажмите ссылку на мое приложение, оно откроется в новом окне
  • Кнопка Release Shift

keyup Событие не будет срабатывать на моей странице, когда оно не будет сфокусировано, поэтому мое приложение покажет, когда я снова сосредоточусь на вкладке "Мои приложения", это покажет, что нажата клавиша Shift.

Было бы хорошо, если события видимости страницы имели свойства ключа-модификатора. Увы, они не делают.

document.addEventListener('webkitvisibilitychange', function(e) {
    if (document.webkitHidden) return;

    e.altKey // undefined :(

}, false);

Ответ 1

Лучшее, что я придумал до сих пор:

document.body.onkeydown = function(e) {
  if (e.which === 18) {
    alt_state.textContent = 'pressed';
  }
};

document.body.onkeyup = function(e) {
  if (e.which === 18) {
    alt_state.textContent = 'released';
  }
};

function detectAlt() {
  if (document.webkitHidden) return;
  window.addEventListener('mousemove', function onMove(e) {
    alt_state.textContent = e.altKey ? 'pressed' : 'released';
    window.removeEventListener('mousemove', onMove, false);
  }, false);
}

document.addEventListener('webkitvisibilitychange', detectAlt, false);
window.addEventListener('load', detectAlt, false);

Нажмите клавишу alt и щелкните по ссылке: jsbin.

Он полагается на событие mousemove, которое, в отличие от событий load и visibilitychange, имеет свойство altKey. Как недостаток, он не обнаруживает altKey, пока человек не перемещает мышь.

Ответ 2

Я мог бы подумать о двух вариантах:

  • Использовать временный "alt status" → через 2 секунды объявить alt не нажатым.

    document.body.onkeydown = function(e) { if (e.which === 18) { alt_state.textContent = 'pressed'; setTimeout(function(){ alt_state.textContent= ""; },2000); } };

  • Когда видимость теряется просто reset все флаги alt.

    document.addEventListener('webkitvisibilitychange', function(e) {
        if (document.webkitHidden){
            altPressed = "";
            return;
        }
    }, false);
    

попробуйте следующее: http://jsbin.com/jihuyibu/1/edit Это мое лучшее предположение, даже потому, что он никогда не выходит отлично.