13
votes

My app changes its state when a person holds modifier keys (Shift, Alt, Ctrl). I track modifier keys using keydown/keyup events:

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

Keyboard events don’t trigger outside of the browser tab. Now, imagine the following scenario:

  1. Hold Shift key
  2. Click on a link to my app, it will open in a new window
  3. Release Shift key

keyup event won’t fire on my page when it isn’t focused so my app will show when I focus on my app’s tab again it will show the Shift key still being pressed.

Would be nice if page visibility events had modifier key properties. Alas, they don’t.

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

    e.altKey // undefined :(

}, false);
2
So, you want to know what keys were pressed down before the page was loaded? If so, it might be a rough road... - rvighne
can you give a reason why you want to do that? the page could be loaded in background so it could not always get the key event - charlee
What problem are you actually trying to solve? So far, it looks like you're just describing a behavior you've observed and I'm not seeing a particular problem description that you need help with solving. - jfriend00
@jfriend00: Check out the original revision; for some reason the OP edited out the actual question. - rvighne
I think the point is for alt/shift/etc to not still be pressed after returning to the app, in better terms, to detect it has been released when returning to the app. - JDuarteDJ

2 Answers

4
votes

The best I came up so far:

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

Press alt key and click on the link: jsbin.

It relies on mousemove event which, unlike load and visibilitychange events, has altKey property. As a downside, it won’t detect altKey until a person moves the mouse.

1
votes

I could think of 2 options:

  1. Use a timed "alt status" --> after 2 seconds declare alt unpressed.

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

  2. When visibility is lost simply reset all alt flags.

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

try this: http://jsbin.com/jihuyibu/1/edit It's my best guess, even so it never comes out perfectly.